不同于上一次文章,这次使用Redux实现TodoList,然后再美化一下。
最后效果
Redux
关于Redux,Redux 是 JavaScript 状态容器,提供可预测化的状态管理。可以让你构建一致化的应用,运行于不同的环境(客户端、服务器、原生应用),并且易于测试。不仅于此,它还提供 超爽的开发体验。
下面Redux中代码的核心,全部都围绕这一张图进行。
简单理解
- 可以直接跳到TodoList。查看具体的代码。
从上面的图中可以看到。有四个部分。直观看很难理解。但简化来看整个流程可以比作一次借书的流程。
首先蓝色的React Compontents
是每个页面上的组件可以当做借书用户
。
棕色Action Creators
是组件传递的信息,他给Store说要获取什么信息。可以当做借什么书要说的话
橙色Store
是存储数据的公共区域,它接收到要获取的信息。但是他不知道从哪下手。需要传递给后面处理。可以当做图书的管理员
。他知道你要借书但是因为书太多他记不住。他需要一个记录本。
紫色Reducers
是处理信息的区域。它接收到Store传递的信息。它理解该怎么去处理这些信息。可以当做图书信息的记录本
。
整个流程
那么从头梳理一下。
借书之前借书人必须存在(存在一个组件)
借书人说了一句话,要借什么什么。(组件传递信息要获取什么什么)
这是图书的管理员听见了,他要帮你找这本书。因为图书太多了他记不住,所以需要从记录本中查阅相关的信息。知道这本书在哪后。管理员去处理寻找。(Store接收到了信息,但是他不处理信息。给Reducers来处理。Reducers处理完成后告诉Store该怎么去修改数据)
他处理好找到了这本书后。然后把这本书给借书人。(Store知道该怎么修改数据,完成后返回给组件)
美化样式
这步可以忽略,不影响后面的实现。
传统的输入框、按钮不是特别好看。自己美化又麻烦。所以直接引用Ant Design
使用方法
首先安装Ant Design
$ npm install antd --save
//或者
$ yarn add antd
接下来引入主样式文件,之后按需引入加载相应的独立组件即可。具体的可以到官网查看文档。这里就不过多介绍了。
import 'antd/dist/antd.css';
TodoList
实现TodoList并不难。关键是如何引入并使用Redux。
引入Redux
npm install --save redux
//安装稳定版
创建Store
首先在src
目录需要创建一个文件夹store
。在store
中创建index.js
文件。代码如下。
import {createStore} from 'redux';
import reducer from './reducer';
//创建store
const store = createStore(
reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
export default store;
创建reducer
同样在store
下创建reducer.js
文件。代码如下
const defaultState = {
inputValue : '',
list: []
}
//reducer 可以接受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_todo_item'){
const newState = JSON.parse(JSON.stringify(state));
newState.list.push(newState.inputValue);
newState.inputValue = '';
return newState;
}
if (action.type === 'delete_todo_item') {
const newState = JSON.parse(JSON.stringify(state));
newState.list.splice(action.index,1);
return newState;
}
return state;
}
创建TodoList
在src
目录下创建组件TodoLis
。代码如下。
import React, { Component } from 'react';
//引入Ant
import 'antd/dist/antd.css';
//引入Input
import { Input } from 'antd';
//引入自定义样式
import './css1.css'
//引入Button
import { Button } from 'antd';
//引入List
import { List } from 'antd';
//引入redux
import store from './store/index';
class TodoList extends Component{
constructor(props) {
super(props);
this.state = store.getState();
this.handleInputChange = this.handleInputChange.bind(this);
this.handleStoreChange = this.handleStoreChange.bind(this);
this.handleButtonChange = this.handleButtonChange.bind(this);
//监听store里的数据,如果变幻执行handleStoreChange
store.subscribe(this.handleStoreChange);
}
render(){
return (
<div className={'todo'}>
<div>
<Input
value={this.state.inputValue}
placeholder={'todo info'}
className={'todoinput'}
onChange={this.handleInputChange}
/>
<Button
type="primary"
onClick={this.handleButtonChange}>提交</Button>
</div>
<List
className={'todolist'}
bordered
dataSource={this.state.list}
renderItem={(item,index) => (
<List.Item onClick={this.handleItemDelete.bind(this,index)}>
{item}
</List.Item>
)}
/>
</div>
)
}
handleInputChange(e){
const action = {
type: 'change_input_value',
value: e.target.value
};
store.dispatch(action);
}
handleStoreChange() {
this.setState(store.getState());
}
handleButtonChange(){
const action = {
type: 'add_todo_item'
};
store.dispatch(action);
}
handleItemDelete(index){
const action = {
type : 'delete_todo_item',
index
}
store.dispatch(action);
}
}
export default TodoList;
至此就完成了Redux的TodoList小示例。