目录
ReduxRedux简介工作流程例子 React-ReduxReact-Redux简介例子Redux
Redux简介
Reudx是一款JavaScript状态管理容器,除了和React配合使用,还可以配合JS、Vue使用。
工作流程
Redux采用的是一种发布-订阅的模式。有一个公共仓库store,这个仓库里面存储了整个应用的状态。
当React组件要改变状态的时候,首先会生成一个action,然后通过dispatch函数将aciton派发给store。store会将原来的状态state和action传递给ReducersReducers接收到这两个参数后,会对原来的状态进行修改,得到一个新的状态,再将新的状态回传给store。此时store中的状态改变,然后React组件重新渲染内容。
注意:
整个应用有且仅有一个store,其内部的state tree存储整个应用的statestate是只读的,想要修改state,只能通过派发action到reducers。为了描述action如何改变state,需要编写reducer纯函数。
例子
首先先安装redux模块:
yarn add redux
Counter.js:
import React,{Component} from "react";import store from "../store/store";import {bindActionCreators} from "redux"; //绑定动作生成者//actionsfunction add(){return {type:'ADD'}}function minus(){return {type:'MINUS'}}const actions={add,minus} 把两个动作放到一个对象里面去const bindActions=bindActionCreators(actions,store.dispatch) //把动作对象一次性绑定到dispatch上class Counter extends Component{constructor(props) {super(props);this.state={number:store.getState().count}}componentDidMount() {//最后需要添加上这个函数,用于订阅store,页面上显示的内容才会改变this.unSubscribe=store.subscribe(()=>{this.setState({number:store.getState().count})})}componentWillUnmount() {//组件卸载时取消订阅this.unSubscribe&&this.unSubscribe() //已经订阅,并且调用了取消订阅函数。最后卸载组件就取消订阅}render(){return (<div><p>{this.state.number}</p>{/*<button onClick={()=>store.dispatch({type:'ADD'})}>Count++</button> /!*派发以及action都在触发事件里的写法,dispatch函数用于派发一个action动作*!/*/}{/*<button onClick={()=>store.dispatch({type:'MINUS'})}>Count--</button>*/}<button onClick={bindActions.add}>Count++</button> //action和dispatch绑在一块的写法<button onClick={bindActions.minus}>Count--</button></div>)}}export default Counter;
redux 提供了bindActionCreators
功能,将派发 action 的函数与 store.dispatch 进行绑定。手动导入store文件,手动订阅storestore提供getState()
方法获取state;dispatch(action)
方法更新state;subscribe(listener)
注册监听器。
store.js:
import {createStore} from 'redux'; //createStore函数,用来生成Storeexport const ADD='ADD'; //定义接收到的动作export const MINUS='MINUS';function reducer(state={count:0},action){switch(action.type){case ADD:return {count:state.count+1}case MINUS:return {count:state.count-1}default:return state}}//创建storelet store=createStore(reducer)export default store;
Redux 提供createStore
这个函数,用来生成 Store。reducer
必须是个纯函数,接收state
,action
两个参数。state 是旧的状态,不可直接修改,而是需要根据 action.type 不同,来生成新的 state 并返回。
App.js:
可以看出,在React组件中使用store,需要手动引入store文件,手动订阅store中状态的变化,这是不合理的,接下来看看React-Redux是如何做的。
React-Redux
React-Redux简介
React-Redux是Redux的官方React绑定库。能够使React组件从Redux store中读取数据,并且向store分发actions以更新数据。
例子
React-Redux不是Redux的内置,需要单独安装,两者一般结合使用。
(1)首先安装模块:
npm install reduxnpm install react-redux
(2)创建一个store.js文件
import {createStore} from "redux";export const ADD='ADD';export const MINUS='MINUS';function reducer(state={count:0},action){console.log('Action:',action)switch(action.type){case ADD:return{count:state.count+1}case MINUS:return {count:state.count-1}default:return state;}}let store=createStore(reducer);export default store;
(3)index.js文件进行配置
import React from 'react';import ReactDOM from 'react-dom';import './index.css';import App from './App';import {Provider} from "react-redux";import store from "./react_redux/store/store";ReactDOM.render(<Provider store={store }><App /></Provider>,document.getElementById('root'));
Provider
是react-redux提供的一个React组件,用于把state传给它的所有子组件。这里Provider的子组件是App,而App的子组件包含Counter组件,所以就可以从这里将store里面的state传递给Counter组件。
App.js:
import Counter from "./react_redux/components/1counter";function App() {return (<div className="App"><header className="App-header"><Counter/></header></div>);}export default App;
Counter组件:
import React,{Component} from "react";import {connect} from "react-redux";import action from "../action/action";class Counter extends Component{render(){return (<div><p>{this.props.count}</p><button onClick={this.props.add}>Count++</button> <button onClick={this.props.minus}>Count--</button></div>)}}const mapStateToProps=(state)=>state //得到当前的state(state是store里面的,通过index,js中Provider分发state——>App——>Counter)const mapDispatchToProps={...action} //得到actionexport default connect(mapStateToProps,mapDispatchToProps)(Counter) //把state和dispatch的动作绑定到当前组件Counter,生成一个新的组件
connect
:高阶组件,给它传入一个组件,它会返回新的组件。mapStateToProps
:定义该参数,组件监听Redux store的变化。任何时候只要store发生变化,mapStateToProps函数就会被调用。(相当于将state放入了props中)mapDispatchToProps
:如果传递的是一个对象,那么该对象里的每一个函数都将作为Redux action creator。(相当于把action里面的所有动作都放到props中)
action.js:
function add(){return {type:'ADD'}}function minus(){return {type:'MINUS'}}const action={add,minus}//把动作打包到常量export default action;
action是store数据的唯一来源,它是一个对象,里面必须有type来指定其类型。