一、Redux
什么时候才会需要用到Redux
Redux 是负责组织 state 的工具,但你也要考虑它是否适合你的情况。不要因为有⼈告诉你要用 Redux 就去用,花点时间好好想想使用了 Redux 会带来的好处或坏处。
在下面的场景中,引入 Redux 是⽐较明智的:
1.你有着相当⼤量的、随时间变化的数据;
2.你的 state 需要有一个单一可靠数据来源;
3.你觉得把所有 state 放在最顶层组件中已经⽆法满足需要了;
4.某个组件的状态需要共享;
![](https://img.haomeiwen.com/i1461605/2700e1814fe55ad3.png)
redux 是 JavaScript应用的状态容器,提供可预测化的状态管理。它保证程序行为一致性且易于测试。
![](https://img.haomeiwen.com/i1461605/8fa6a253de617567.png)
如何安装Redux
npm install redux --save
Redux举例
用一个累加器举例
1. 需要⼀个store来存储数据
2. store里的reducer初始化state并定义state修改规则
3. 通过dispatch⼀个action来提交对数据的修改
4. action提交到reducer函数里,根据传入的action的type,返回新的state
ReduxPage.js文件内容如下:
import React, { Component } from "react";
import store from "../store";
export default class ReduxPage extends Component {
componentDidMount() {
store.subscribe(() => {
console.log("state发生了变化");
this.forceUpdate();
})
}
add = () => {
store.dispatch({type: "ADD"})
}
minus = () => {
store.dispatch({type: "MINUS"})
}
render() {
console.log("store", store);
return (
<div>
<h3>ReduxPage</h3>
<p>{store.getState()}</p>
<button onClick={this.add}>add</button>
<button onClick={this.minus}>minus</button>
</div>
)
}
}
store文件夹下面的index.js文件内容如下:
import { createStore } from "redux";
// 定义state初始化和修改规则,reducer是一个纯函数
function counterReducer(state = 0, action) {
console.log("state", state);
switch(action.type) {
case "ADD":
return state + 1;
case "MINUS":
return state - 1;
default:
return state;
}
}
const store = createStore(counterReducer);
export default store;
如果点击按钮不能更新,因为没有订阅(subscribe)状态变更
检查点
1. 通过createStore 创建store
2. reducer 初始化、修改状态函数
3. getState 获取状态值
4. dispatch 提交更新
5. subscribe 变更订阅
二、react-redux
如何安装react-redux
npm install react-redux --save
如何使用react-redux
react-redux提供了如下两个api:
Provider 为后代组件提供store
connect 为组件提供数据和变更⽅法
全局提供store
index.js文件内容如下:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import store from './store';
import { Provider } from 'react-redux'
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
);
App.js文件内容如下:
import ReactReduxPage from './pages/ReactReduxPage';
function App() {
return (
<div>
<ReactReduxPage />
</div>
);
}
export default App;
store文件夹下面的index.js文件内容如下:
import { createStore } from "redux";
// 定义state初始化和修改规则,reducer是一个纯函数
function counterReducer(state = 0, action) {
console.log("state", state);
switch(action.type) {
case "ADD":
return state + 1;
case "MINUS":
return state - 1;
default:
return state;
}
}
const store = createStore(counterReducer);
export default store;
connect中的参数:state映射和事件映射
ReactReduxPage.js文件内容如下:
方案1:
import React, { Component } from "react";
import { connect } from "react-redux"
export default connect(
// mapStateToProps把state映射到props
state => ({ num: state })
)
(class ReactReduxPage extends Component {
render() {
const { num, dispatch } = this.props;
console.log("props", this.props); // {num: 0, dispatch: f}
return (
<div>
<h3>ReactReduxPage</h3>
<p>{num}</p>
<button onClick={() => dispatch({type: "ADD"})}>add</button>
<button onClick={() => dispatch({type: "MINUS"})}>minus</button>
</div>
)
}
})
方案2:
import React, { Component } from "react";
import { connect } from "react-redux"
class ReactReduxPage extends Component {
render() {
const { num, add, minus } = this.props;
console.log("props", this.props); // {num: 0, add: f, minus: f}
return (
<div>
<h3>ReactReduxPage</h3>
<p>{num}</p>
<button onClick={add}>add</button>
<button onClick={minus}>minus</button>
</div>
)
}
}
// mapStateToProps把state映射到props
const mapStateToProps = state => ({ num: state })
// mapDispatchToProps把dispatch映射到props
const mapDispatchToProps = {
add: () => ({ type: "ADD" }),
minus: () => ({ type: "MINUS" })
}
export default connect(
mapStateToProps, // 状态映射
mapDispatchToProps // 派发事件映射
)(ReactReduxPage);
网友评论