Redux
Redux简介
Reudx是一款JavaScript状态管理容器,除了和React配合使用,还可以配合JS、Vue使用。
工作流程
Redux采用的是一种发布-订阅的模式。有一个公共仓库store,这个仓库里面存储了整个应用的状态。
- 当React组件要改变状态的时候,首先会生成一个action,然后通过dispatch函数将aciton派发给store。
- store会将原来的状态state和action传递给Reducers
- Reducers接收到这两个参数后,会对原来的状态进行修改,得到一个新的状态,再将新的状态回传给store。
- 此时store中的状态改变,然后React组件重新渲染内容。
注意:
- 整个应用有且仅有一个store,其内部的state tree存储整个应用的state
- state是只读的,想要修改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";
function add(){
return {
type:'ADD'
}
}
function minus(){
return {
type:'MINUS'
}
}
const actions={add,minus}
const bindActions=bindActionCreators(actions,store.dispatch)
class Counter extends Component{
constructor(props) {
super(props);
this.state={
number:store.getState().count
}
}
componentDidMount() {
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={bindActions.add}>Count++</button>
<button onClick={bindActions.minus}>Count--</button>
</div>
)
}
}
export default Counter;
- redux 提供了
bindActionCreators 功能,将派发 action 的函数与 store.dispatch 进行绑定。 - 手动导入store文件,手动订阅store
- store提供
getState() 方法获取state;dispatch(action) 方法更新state;subscribe(listener) 注册监听器。
store.js:
import {createStore} from 'redux';
export 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
}
}
let 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 redux
npm 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
const mapDispatchToProps={...action}
export default connect(mapStateToProps,mapDispatchToProps)(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来指定其类型。
|