1、什么是Redux
Redux 是React生态中重要的组成部分。很多人都说,简单的应用可以不用此工具。但是我个人认为,中小型应用使用的话,可以使文件结构更加规范,代码可读性更强。因为React提出将展示组件与容器组件分离的思想,所以降低了React 与Redux之间的耦合度。
Redux是一个流行的JavaScript框架,为应用程序提供一个可预测的状态容器。Redux基于简化版本的Flux框架,Flux是Facebook开发的一个框架。在标准的MVC框架中,数据可以在UI组件和存储之间双向流动,而Redux严格限制了数据只能在一个方向上流动。 见下图:
在Redux中,所有的数据(比如state)被保存在一个被称为store
的容器中 → 在一个应用程序中只能有一个。store
本质上是一个状态树,保存了所有对象的状态。任何UI组件都可以直接从store
访问特定对象的状态。要通过本地或远程组件更改状态,需要分发一个action
。分发在这里意味着将可执行信息发送到store
。当一个store
接收到一个action
,它将把这个action
代理给相关的reducer
。reducer
是一个纯函数,它可以查看之前的状态,执行一个action
并且返回一个新的状态。
Redux的运行原理
store中重要的方法
2、配置Redux
配置Redux开发环境的最快方法是使用create-react-app
工具。在开始之前,确保已经安装并更新了nodejs
,npm
。
npm install redux
创建store目录,在store目录下新建index.js文件,键入以下内容:
import {createStore} from 'redux';
import reducer from './reducer';
const store = createStore(reducer);
export default store;
在store目录下创建reducer.js文件,键入以下内容:
const defaultState = {
inputValue:'',
list:[]
}
//reducer可以接收state,但是不能修改state
export default (state = defaultState,action) => {
return state;
}
在组件中就可以使用store的数据
import React,{Component} from 'react';
import store from './store/index';
class TodoList extends Component{
constructor(props){
super(props);
this.state = store.getState();
this.handleStoreChange = this.handleStoreChange.bind(this);
store.subscribe(this.handleStoreChange);
}
handleStoreChange(){
this.setState(store.getState());
}
render(){
return (
<div>
<input type='text' value={this.state.inputValue}/>
<button onClick={this.handleClick}>提交</button>
<ul>
{this.state.list.map((item,index)=>{
return (
<li key={index}>{item}</li>
);
})}
</ul>
</div>
);
}
}
export default TodoList;
3、TodoList案例
TodoList.js
import React,{Component} from 'react';
import store from './store/index';
import {DELETE_TODO_ITEM,CHANGE_INPUT_VALUE,ADD_TODO_ITEM} from './store/actionType'
class TodoList extends Component{
constructor(props){
super(props);
this.state = store.getState();
this.handleChange = this.handleChange.bind(this);
this.handleStoreChange = this.handleStoreChange.bind(this);
this.handleClick = this.handleClick.bind(this);
store.subscribe(this.handleStoreChange);
}
handleChange(e){
const action = {
type:CHANGE_INPUT_VALUE,
value:e.target.value
}
store.dispatch(action);
}
handleStoreChange(){
this.setState(store.getState());
}
handleClick(){
const action = {
type:ADD_TODO_ITEM
}
store.dispatch(action);
}
handleClickItem(index){
const action = {
type:DELETE_TODO_ITEM,
index:index
}
store.dispatch(action);
}
render(){
return (
<div>
<input type='text' value={this.state.inputValue} onChange={this.handleChange} />
<button onClick={this.handleClick}>提交</button>
<ul>
{this.state.list.map((item,index)=>{
return (
<li key={index} onClick={this.handleClickItem.bind(this,index)}>{item}</li>
);
})}
</ul>
</div>
);
}
}
export default TodoList;
store/index.js
import {createStore} from 'redux';
import reducer from './reducer';
const store = createStore(reducer);
export default store;
store/reducer.js
import {DELETE_TODO_ITEM,CHANGE_INPUT_VALUE,ADD_TODO_ITEM} from './actionType'
const defaultState = {
inputValue:'',
list:[]
}
//reducer可以接收state,但是不能修改state
export default (state = defaultState,action) => {
console.log(state,action);
if(action.type === CHANGE_INPUT_VALUE){
const newState = state;
newState.inputValue = action.value;
return newState;
}
if(action.type === ADD_TODO_ITEM){
const newState = state;
newState.list.push(newState.inputValue);
newState.inputValue = '';
return newState;
}
if(action.type === DELETE_TODO_ITEM){
const newState = state;
newState.list.splice(action.index,1);
return newState;
}
return state;
}
store/actionType.js
export const CHANGE_INPUT_VALUE = 'change_input_value'
export const ADD_TODO_ITEM = 'add_todo_item'
export const DELETE_TODO_ITEM = 'delete_todo_item'
核心API:
- createStore 创建store
- store.dispatch 派发action,把数据上传到Store中
- store.getState 获取store中所有的数据内容,但是Store中的数据发生变化时,组件不会知道
- store.subscribe 监听Store中的数据变化,Store中的数据一旦发生变化,该方法就会被执行