theme: fancy
上篇文章简单讲了 redux ,本文讲解redux 搭配 React 。
需要先安装
安装 React Redux
npm install --save react-redux
常用使用方法
import {Provider, connect, combineReducers, bindActionCreators} from "react-redux";
- Provider 提供者:挂载传递store, 类比react context
- connect connect 连接:映射 store, dispatch 到组件,connect(mapStoreToProps, mapDispatchToProps )(组件component)
- combineReducers 组合 多个 Reducer
- bindActionCreators 作用是将单个或多个ActionCreator转化为dispatch(action)的函数集合形式
1. 定义 action
- 新建文件 actions.js
function add() {
return {type: "ADD"};
}
function minus() {
return {type: "MINUS"}
}
const actions = {add, minus};
export default actions;
2. 定义 Reducer
- 新建文件 reducer.js
import {
add,
minus
} from './actions'
// 定义常量
// export const ADD = "ADD";
// export const MINUS = "MINUS";
import {
add,
minus
} from './actions'
// 首次初始化 count 为 0
function reducer(state={count: 0}, action) {
console.log('reducer -- action', action , state);
switch (action.type){
case add.type:
return {count: state.count + 1};
break;
case minus.type:
return {count: state.count - 1};
break;
default:
return state;
}
}
3. 定义 Store
- 新建文件 Store.js
import {createStore, combineReducers} from 'redux';
import reducer from './reducer';
import reducer2 from './reducer2';
// 如有多个 reducer, 则都引入,用 combineReducers 将多个 reducer 合并成为一个
const todoApp = combineReducers({ reducer, reducer2 ... })
// 创建一个 Redux [store] 来以存放应用中所有的 state。
const store = createStore(todoApp);
export default store;
4. 传入 Store
- 所有容器组件都可以访问 Redux store,所以可以手动监听它。一种方式是把它以 props 的形式传入到所有容器组件中。但这太麻烦了,因为必须要用 `store` 把展示组件包裹一层,仅仅是因为恰好在组件树中渲染了一个容器组件。
- 建议的方式是使用指定的 React Redux 组件 [`<Provider>`](https://github.com/reactjs/react-redux/blob/master/docs/api.md#provider-store) 来 [魔法般的](https://facebook.github.io/react/docs/context.html) 让所有容器组件都可以访问 store,而不必显示地传递它。只需要在渲染根组件时使用即可。
- 新建入口文件
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {Provider} from "react-redux";
import store from "./store";
ReactDOM.render(
<Provider store={store}>
<App/>
</Provider>,
document.getElementById('root')
);
App.js 文件
import Counter from "./counter";
// 容器组件
function App() {
return (
<div className="App">
<Counter/>
</div>
);
}
export default App;
5. 使用 connect() 创建 Counter
Counter 组件中
import React from "react";
import {connect} from "react-redux";
import actions from "./actions";
class Counter extends React.Component {
render() {
console.log('Counter,this.props', this.props)
return (
<>
<p>Count:{this.props.count}</p>
<br/>
<button onClick={this.props.dispatch(actions.add)}>Count++</button>
<button onClick={this.props.dispatch(actions.minus)}>Count--</button>
</>
);
}
}
// 将store中的state和需要store派发的action绑定到组件中
export default connect()(Counter);
或者
import React from "react";
import {connect} from "react-redux";
import actions from "./actions";
class Counter extends React.Component {
render() {
console.log('Counter,this.props', this.props)
return (
<>
<p>Count:{this.props.count}</p>
<br/>
<button onClick={this.props.add}>Count++</button>
<button onClick={this.props.minus}>Count--</button>
{/* 这样的时候需要吧mapDispatchToProps去掉,否则把 dispatch map 丢了 */}
{/* <br/>
<button onClick={ ()=> this.props.dispatch({type: 'ADD'})}>Count++</button>
<button onClick={ ()=> this.props.dispatch(actions.add)}>Count++</button>
<button onClick={ ()=> this.props.dispatch({type: 'MINUS'})}>Count--</button>
<button onClick={ ()=> this.props.dispatch(actions.minus)}>Count--</button>*/}
</>
);
}
}
// 函数,这个函数允许我们将 `store` 中的数据作为 `props` 绑定到组件上。
// state 是store 中的数据 , ownProps 是组件的 props 数据
const mapStateToProps = (state, ownProps) => {
return {
count: state.count
}
}
//对象:保存的action
const mapDispatchToProps = (dispatch, ownProps) => {
add: ()=>{
dispatch(actions.add)
},
minus: ()=>{
dispatch(actions.minus)
},
}
// 将store中的state和需要store派发的action绑定到组件中
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
connect() 接收四个参数,它们分别是 mapStateToProps , mapDispatchToProps, mergeProps 和 options 。
注意 mapStateToProps,mapDispatchToProps的使用
mapStateToProps
这个函数允许我们将 store 中的数据作为 props 绑定到组件上。
const mapStateToProps = (state) => {
return {
count: state.count
}
}
mapDispatchToProps
const mapDispatchToProps = (dispatch, ownProps) => {
return {
add: ()=>{
dispatch(actions.add)
},
minus: ()=>{
dispatch(actions.minus)
}
}
}
1.previder 提供者:挂载传递store, 类比react context 2.connect 连接:映射 store, dispatch 到组件 。connect(mapStoreToProps, mapDispatchToProps )(组件component)
其他状态管理库
recoil
dva