前言
学习react之后,我们知道react中的传值是通过props,但其仅限于父子组件之间的传值,如果一个项目层级很深(如某个全局样式),而又需要从第一个层级传到最后一个层级,如果使用props一层一层的传值很麻烦,而且容易出错,所以针对这个问题,使用react-redux比较好!
以前的文章写过上下文传值的方式,但其也比较麻烦,慎重,容易给自己挖坑!
虽然redux和react-redux的实现原理也是在上下文的基础上实现的,但是其被封装并且已经比较成熟完善
redux是react中比较难学的知识点,此文只是简单的记录其基本用法,具体还需要另外学习
redux的使用
使用redux前先安装redux
npm install redux --save
使用redux值传递流程
流程:
- 创建⼀一个store来存储数据
- store里的reducer初始化state并定义state修改规则
- 通过dispatch⼀一个action来提交对数据的修改
- action提交到reducer函数⾥里里,根据传⼊入的action的type,
返回新的state
代码示例:
//定义修改规则
function countReducer(state = 0, action) {
switch (action.type) {
case "ADD":
return state + 1;
case "MINUS":
return state - 1;
default:
return state;
}
}
创建store并传入Reducer
import {createStore} from "redux";
const store = createStore(countReducer);
export default store;
通过dispatch⼀一个action来提交对数据的修改
import React, {Component} from "react";
import store from "../store/";
export default class ReduxPage extends Component {
componentDidMount() {
// 订阅
store.subscribe(() => {
this.forceUpdate();
});
}
add = () => {
// 派发操作
store.dispatch({type: "ADD"});
};
minus = () => {
store.dispatch({type: "MINUS"});
};
asyAdd = () => {
// 派发操作
store.dispatch(dispatch => {
setTimeout(() => {
dispatch({type: "ADD"});
}, 1000);
});
};
render() {
console.log("store", store); //sy-log
return (
<div>
<h3>ReduxPage</h3>
{/* getState获取数据 */}
<p>{store.getState()}</p>
<button onClick={this.add}>add</button>
<button onClick={this.minus}>minus</button>
<button onClick={this.asyAdd}>asyAdd</button>
</div>
);
}
}
PS:允许使用store.subscribe方法设置监听函数,一旦 State 发生变化,就自动执行这个函数,如state一旦发生改变,则强制刷新页面
// 订阅
store.subscribe(() => {
this.forceUpdate();
});
}
react-redux的使用
使用redux每次都要使用store.getState()才能获取最新的state,很麻烦,所有react就写了react-redux
安装
npm install react-redux --save
react-redux在原来的基础上多提供了两个api,分别是Provider和connect
Provider
Provider 为后代组件提供store,即在index入口页面使用provider引入store,后代组件不用再次引入,可直接使用store
//index文件
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import {Provider} from "react-redux";
import store from "./store/";
// 把store放在最顶层
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
//store内容
import {createStore} from "redux";
function countReducer(state = 0, action) {
switch (action.type) {
case "ADD":
return state + 1;
case "MINUS":
return state - 1;
default:
return state;
}
}
const store = createStore(countReducer);
export default store;
connect
connect 为组件提供数据和变更更⽅方法,即connect将所需要的数据和方法和组件绑定,这样就可以哪个组件需要哪些数据直接关联.
如果不使用connect,class组件导出是这样
class SceneMonitor extends React.Component {。。。}
export default SceneMonitor
如果需要讲数据和组件绑定,则导出组件是这样的
class SceneMonitor extends React.Component {。。。}
export default connect(mapStateToProps,mapDispatchToProps)(SceneMonitor)
mapStateToProps
该回调函数必须返回⼀一个纯对象,这个对象会与组件的props 合并。如果定义该参数,组件将会监听 Redux store 的变化,否
则 不不监听
mapDispatchToProps
如果你省略略这个 mapDispatchToProps 参数,默认情况下, dispatch 会注⼊入到你的组件 props 中。
const mapStateToProps = state => {
return {
num: state,
};
};
const mapDispatchToProps = {
add: () => {
return { type: "add" };
},
minus: () => {
return { type: "minus" };
}
};
export default connect(
mapStateToProps, //状态映射 mapStateToProps
mapDispatchToProps, //派发事件映射
)(ReactReduxPage);