总结
- immutable.js库/redux-immutable库 都可生成不可改变的immutable对象,但使用场景不同。
- **immutable.js库的fromJS()**:接受组件的state对象,返回immutable对象类型的state。
- **redux-immutable库的combineReducers()**:接受各个组件的reducer,返回immutable对象类型的 总state。
- 想要获取immutable对象的属性则需要使用**get()**。
- immutable对象的set()不会改变原本的immutable对象,它返回的是新的immutable对象。
- 注意:fromJS会自动 将对象中的数组 变成 immutable类型的数组,所以使用set()修改immutable类型数组时要求修改的数据也是immutable类型的,否则数据类型就乱了。所以我们要使用fromJS使set()的参数2也成为immutable类型
拆分actionCreators与constants
- actionCreators.js里都是函数,每个函数都返回对应的action。
- constants.js即我们之前使用过的actionTypes.js,用于将action的type从字符串定义为常量的文件。
- 在common-header-store文件夹下新建actionCreators.js和constants.js,他们都要通过index.js进行输出(store文件夹下的所有文件都通过index.js输出,这样 外部文件 引用时统一引用到store文件夹即可)
拆分constants.js
1.common-header-store 新建constants.js 将action的type从字符串定义为常量:
1 | //加一个`header/`表示是header下的,对后续维护有好处 |
2.在common-header-store-index.js中引入、输出constants.js,统一对外接口路径:
1 | import reducer from "./reducer"; |
3.header-index.js中,引入constants并修改原本的action的type(字符串=>常量):
1 | import { constants } from "./store"; |
(注意:两个常量都是从constants中获取的,constants输出时使用了*
,所以调用常量时都要使用constants
前缀)
4.common-header-store-reducer.js中,引入constants并修改action.type:
1 | import * as constants from "./constants"; |
拆分actionCreators.js
1.common-header-store新建actionCreators.js,里面的每个函数都返回对应的action:
1 | import { constants } from "../store"; |
2.在common-header-store-index.js中统一对外接口:
1 | import reducer from "./reducer"; |
3.在common-header-store-reducer.js中引入并使用actionCreators中的函数来返回对应action:
1 | import { constants, actionCreators } from "./store"; |
(**注意:调用的是actionCreators中的函数,所以记得()
**)
immutable.js库 生成不可改变的对象
- mutable 可变的,易变的 => immutable 不可变的
- immutable.js是facebook推出的第三方模块(库),它可以帮我们建一个不可改变的immutable对象。
- 更多知识点可参考immutable.js官网文档,比如fromJS()的详细用法
使用immutable.js管理store中的数据
- reducer中拿到的store的state是不应该被改变的,为防止不小心改变,我们可以将state变成immutable对象。
- 生成immutable对象:使用 immutable库 的fromJS()
- 获取immutable对象的属性:使用 immutable对象 的get()(注意参数是字符串)
- 修改并返回新的immutable对象:使用 immutable对象 的set()
安装immutable库
可参考immutable.js官方文档:
1 | yarn add immutable |
immutable库的fromJS()生成immutable对象
- immutable库的
fromJS
可用于生成immutable对象 - 引入:
import {fromJS} from "immutable";
- 使用:
const immutable = fromJS({对象属性:属性值});
(fromJS()
接受一个对象,并返回immutable对象)
header-reducer.js中,使用immutable库的fromJS
来生成immutable对象,替代原本的state默认值:
1 | import { fromJS } from "immutable"; |
immutable对象的get()获取对象属性
- 想要获取immutable对象的属性值不能通过
对象名.属性名
的方式,需要使用对象名.get("属性名")
- 注意:get()接受的参数为字符串
header-index.js中,原本的state已经变成immutable对象,所以需要使用get()来获取属性:
1 | const mapStateToProps = (state) => { |
注意:state是JS对象,state.header是immutable对象,所以获取属性的方法才不同。
immutable对象的set()返回新对象
- immutable对象的set()接受两个参数,返回新对象
- 参数1:(字符串)想要修改的对象的属性
- 参数2:想要修改的属性值
- 语法:
immutable对象.set("属性名",属性值)
- 注意:immutable对象 是不可改变的,set()不会改变 immutable对象,他会结合 之前的immutable对象的值 和 通过参数修改的值,返回全新的对象。
header-reducer.js中,需要返回新的state,即新的immutable对象:
1 | export default (state = defaultState, action) => { |
补充:getIn()代替连续get()
- 想要获取immutable对象的属性的属性时可使用getIn()
- 详细用法可参考immutable.js官方文档
- getIn()接受一个数组作为参数,数组元素为字符串类型
immutable对象.getIn(["参数1","参数2"])
表示获取immutable对象的参数1下的属性2。
1 | immutable对象.get("属性名a").get("属性名b") |
补充:merge()代替连续set()
- 详细用法可参考官方文档
- 需要连续修改数据后返回immutable对象时,可使用merge()合成多次修改。
1 | immutable对象.set("属性名a",属性值a).set("属性名b",属性值b) |
补充:ToJS()将immutable对象=>JS对象
- 注意:对象包括数组
- 语法:
const JS对象 = immutable对象.toJS();
- 作为state,我们不希望他改变,但是state中的数组我们是可以允许改变的,将state生成为immutable对象时顺便生成的immutable数组就可使用ToJS()将其转换为JS数组,以方便修改。
在reducer中,我们将state生成为immutable对象后,其中的数组也会成为immutable数组:
那后续的数组修改就会变得很麻烦,所以想要修改数组前可使用ToJS()将immutable数组转回JS数组:
1 | const newList = list.toJS(); |
redux-immutable库 生成不可改变的对象
- 上面我们知道了,通过 immutable库的fromJS() 可在组件的reducer中生成immutable对象类型的state。
- 使用redux-immutable库的combineReducers()合成各个组件的reducer得到的就是immutable对象
- 想要获取immutable对象的属性的属性时可使用getIn()
使用redux-immutable统一数据格式
- header下的reducer中的state是immutable对象。
- 但项目最外层的state还是JS对象,这个state是在src-store-reducer.js中创建的。
在header-index.js中,state是JS对象,state.header是immutable对象:
1 | const mapStateToProps = (state) => { |
- 原本项目最外层的state是使用redux的combineReducers()合成各个组件的reducer得到的。
- 但immutable库的fromJS()接受的参数是对象,不具有结合reducer们的能力,最外层state是由许多reducer合成而来,不能使用fromJS()。
- 而使用redux-immutable库的combineReducers()合成各个组件的reducer得到的就是immutable对象
安装redux-immutable库
1 | yarn add redux-immutable |
redux-immutable库的combineReducers()生成immutable对象
- state是由reducer进行 定义/修改 返回给store的。
- 原本我们使用redux提供的combineReducers()生成的reducer返回的state是JS对象
- 现在改成使用redux-immutable库提供的combineReducers()生成immutable对象类型的state返回给store
src-store-reducer.js:
只需改成使用redux-immutable库提供的combineReducers()即可使生成的reducer(即state)为immutable对象
使用immutable对象的get()
**header-index.js中,**由于最外层state也成为了immutable对象,所以获取state的header时要使用get():
1 | const mapStateToProps = (state) => { |
immutable对象的getIn()获取属性的属性
上面header-index.js的代码可改为:
1 | const mapStateToProps = (state) => { |