在React中通过state进行数据的维护,并且当数据共享的时候需要状态提升,但是当数据过多的时候或者项目较大的时候,使用状态提升会使得数据比较混乱,并且不好维护
现在大部分使用react-redux 对数据进行维护
redux 使用文档:http://cn.redux.js.org/
redux文档内容感觉有点混乱,暂时没有全部看。redux获取数据通过查阅相关资料,我看明白了。但是关于如何修改state中的数据,看了网上很多说明,最终还是没有看明白,按照教程说的去做,但是发现仍旧有问题,感觉都没有说明到底是如何更改的,最终通过测试发现了解决方案,记录一下,方便以后再遇到该问题。
我是根据使用react-creat-app 生成的项目的目录进行开发的。
主要文件夹均在src文件夹下
reducer文件夹主要是关于 redux相关文件的位置
首先,需要设置触发的动作–action.js
//动作比较的值
export const CURRENTPAGETITLE='currentPageTitle';
//动作类型
export const action_pageTitle = { type: CURRENTPAGETITLE,text:'current page title' }
这里需要export,以方便其他组件引入
然后,设置动作与ui的连接函数设置–connect.js
/**
* 设置页面的标题,获取标题的值,或者触发动作修改标题
* mapStateToProps这里获取需要的status属性值即可,不需要所有的status
* @type {{mapStateToProps(*): *, mapDispatchToProps(*): *}}
*/
export const pageTitleMap = {
mapStateToProps(state) {
return {pageTitle: state.pageTitle}
},
mapDispatchToProps(dispatch) {
return {
getCurrentPageTitle: () => {
dispatch(action_pageTitle)
}
}
}
}
该对象,主要是用于设置对页面标题维护的参数
mapStateToProps:之所以返回{pageTitle: state.pageTitle},是因为可能需要维护的state属性有很多,但是某组件主要关注的是和标题设置有关的属性,因此只需要取出state.pageTitle就可以了,并把该状态值转化为属性
mapDispatchToProps:是用于设置属性值改变后的触发函数getCurrentPageTitle
React会根据action_pageTitle找到具体的处理函数
然后,动作的处理函数,也即状态的更新函数–redux.js
/**
* 触发的处理函数
* @param state 设置一个初始值,若没有显示该初始值
* @param action
* @returns {({} & {pageTitle: string}){pageTitle: string}}
*/
const getCurrentPageTitle = (state = { pageTitle:'微信自助服务' }, action) => {
const currentPageTitle=state.pageTitle;
switch (action.type) {
case CURRENTPAGETITLE:
return Object.assign({}, state, {
pageTitle: currentPageTitle
})
default:
return state
}
}
这里直接根据CURRENTPAGETITLE确定触发函数的真实处理函数;
/**
* 该方法用于总设置处
* 多个reducer方法 pageTitle: getCurrentPageTitle
* @type {Reducer}
*/
export const allReducer = combineReducers({
pageTitle:getCurrentPageTitle
})
此段代码是因为在redux.js中需要将数据拆分开维护(即只处理state中的某个特定属性,例如,getCurrentPageTitle只维护pageTitle),导致可能有多个类似getCurrentPageTitle的reducer的方法,
combineReducers用于合并所有的reducer,并且方便被调用
其次,是具体的使用
app.js
import React from 'react'
import {createStore} from 'redux'
import {Provider} from 'react-redux'
import {allReducer} from './reducer/reduxs'
/**
* 所有的reducer的合集被store调用
* @type {any}
*/
const store = createStore(allReducer)
class App extends React.Component {
render() {
return (
);
}
}
export default App;
通过Provider将store传给所有被Provider包裹的子组件,所有的子组件都可以通过props获取属性值,与更新方法。如何传递的可以自行查看源码,react-redux的源码封装部分
History.jsx
import React from 'react'
import "../../view/history/history.css";
import {connect} from "react-redux";
import {pageTitleMap} from "../../reducer/connect";
class History extends React.Component {
constructor(props) {
super(props)
//必须此处获取不可以在render()方法中调用,否则会出现无限循环
let {getCurrentPageTitle,pageTitle}=props;
//直接变更mapStateToPropsh中的属性值,在这里不需要设置state
pageTitle.pageTitle='历史记录'
//调用state更新方法
getCurrentPageTitle();
}
render() {
return (
)
}
}
/**
* 通过connect方法连接需要变更的state值与UI
* connect方法必须有,否则
* 通过let {getCurrentPageTitle,pageTitle}=props 获取getCurrentPageTitle,pageTitle会失败
* 第一个参数是将state值转换为属性值的属性,
* 第二个参数是触发state转化为属性值后变更的方法设置属性
*/
export default connect(pageTitleMap.mapStateToProps,pageTitleMap.mapDispatchToProps)(History);
需要注意:
//此处获取必须不可以在render()方法中调用,否则会出现无限循环
let {getCurrentPageTitle,pageTitle}=this.props;
//直接变更属性值,在这里不需要设置state
pageTitle.pageTitle='还款历史记录'
//调用state更新方法
getCurrentPageTitle();
否则报错:
Maximum update depth exceeded.
This can happen when a component repeatedly calls setState
inside componentWillUpdate or componentDidUpdate.
React limits the number of nested updates to prevent infinite loops.