1、什么是Redux
官方解释:Redux is a predictable state container for JavaScript apps. 意思就是Redux是js应用的 一种可预测的状态容器
2、为什么使用Redux
下面的图是不使用Redux和使用Redux时 父子组件之间的通信方式
没有使用Redux的情况,如果两个组件(非父子关系)之间需要通信的话,可能需要多个中间组件为他们进行消息传递,这样既浪费了资源,代码也会比较复杂。
Redux中提出了单一数据源Store 用来存储状态数据,所有的组建都可以通过Action修改Store,也可以从Store中获取最新状态。使用了redux就可以完美解决组建之间的通信问题。
3、怎么使用Redux
下面是通过Redux实现的TodoList 例子,具体的redux安装等,移步这里 redux官网
store: 创建store,用于存储state数据
//store/index.js
import { createStore } from 'redux'
import reducer from './reducer';
const store = createStore(reducer);
export default store;
reducer:根据传入的action 向store返回新的state
//reducer.js
const defaultState = {
inputValue: '',
list: []
}
//reducer 可以接受state但是不能修改state,需要对state进行深拷贝
export default (state = defaultState, action) => {
if (action.type === 'change_input_value') {
const newState = JSON.parse(JSON.stringify(state));
newState.inputValue = action.value;
return newState
}
if (action.type === 'add_input_value') {
const newState = JSON.parse(JSON.stringify(state));
newState.list = [...state.list, state.inputValue]
newState.inputValue = '';
return newState;
}
return state;
}
//TodoList.js
import React, { Component, Fragment } from 'react';
import store from './store';
class TodoList extends Component {
constructor(props){
super(props)
console.log(store);
this.state = store.getState();
this.handleInputChange = this.handleInputChange.bind(this);
this.handleList = this.handleList.bind(this);
this.btnClick = this.btnClick.bind(this);
this.handleStoreChange = this.handleStoreChange.bind(this);
store.subscribe(this.handleStoreChange)
}
handleStoreChange(){
this.setState(store.getState());
}
handleInputChange(e){
const action = {
type: 'change_input_value',
value: e.target.value
}
store.dispatch(action);
}
handleList(){
return this.state.list.map((item) => {
return <li>{item}</li>
})
}
btnClick(){
const action = {
type: 'add_input_value',
value: this.state.inputValue
}
store.dispatch(action);
}
render() {
return (
<Fragment>
<div>
<input
value = {this.state.inputValue}
onChange = {this.handleInputChange}
/>
<button onClick={this.btnClick}>提交</button>
</div>
<ul>
{this.handleList()}
</ul>
</Fragment>
);
}
}
export default TodoList;