redux一个简单的使用案例
在使用react的时候能否看自己是否能上手,也就是自己能不能熟练手写一个todolist这个简单的功能啦,那么话不多说,先来看代码
先看一个主要的组件
import React, {
Component } from 'react'
import 'antd/dist/antd.css'
import {
Input,Button,List} from 'antd'
import Item from 'antd/lib/list/Item'
import store from './store'
import {
changeInputAction, addItemAction, deleteItemAction } from "./store/actionCreatores"
class ReduxTodoList extends Component {
constructor(props) {
super(props)
this.state = store.getState()
this.changeValue=this.changeValue.bind(this)
this.addList=this.addList.bind(this)
this.storeChange = this.storeChange.bind(this) //转变this指向
store.subscribe(this.storeChange) //订阅Redux的状态
}
addList () {
const action =addItemAction()
store.dispatch(action)
}
deleteItem (index) {
const action = deleteItemAction(index)
store.dispatch(action)
}
changeValue (e) {
const action = changeInputAction(e.target.value)
store.dispatch(action)
}
render() {
return (
<div style={
{
margin:"10px",width:'600px'}}>
<Input
placeholder={
this.state.inputValue}
style={
{
margin:"10px",width:'300px'}}
onChange={
this.changeValue}
value={
this.state.inputValue}
/>
<Button type="primary" onClick={
this.addList}>增加</Button>
<List
style={
{
width:'300px'}}
bordered
dataSource={
this.state.list}
renderItem={
(item,index)=>(<List.Item onClick={
this.deleteItem.bind(this,index)}>{
item}</List.Item>)}
/>
</div>
);
}
storeChange () {
this.setState(store.getState())
console.log(this.state)
}
}
export default ReduxTodoList
store文件夹的index.js文件,store为状态管理
import {
createStore } from 'redux' // 引入createStore方法
import reducer from './reducer'
const store = createStore(reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()) // 创建数据存储仓库
export default store //暴露出去
写Redux Action的时候,我们写了很多Action的派发,产生了很多Action Types,如果需要Action的地方我们就自己命名一个Type,会出现两个基本问题:这些Types如果不统一管理,不利于大型项目的服用,设置会长生冗余代码。因为Action里的Type,一定要和Reducer里的type一一对应在,所以这部分代码或字母写错后,浏览器里并没有明确的报错,这给调试带来了极大的困难。
整理分离action的type,便于管理与测试的actionTypes.js文件
export const CHANGE_INPUT = 'changeInput'
export const ADD_ITEM = 'addItem'
export const DELETE_ITEM = 'deleteItem'
ToDoList组件里有很多Action,并且分散才程序的各个地方,如果庞大的工程,这势必会造成严重的混乱,那这节课就把所有的Redux Action放到一个文件里进行管理。把action 抽离出来,更好的actionCreatores.js文件
import {
CHANGE_INPUT, ADD_ITEM, DELETE_ITEM } from "./actionTypes"
export const changeInputAction = (value) => ({
type:CHANGE_INPUT,
value
})
// =>({})---就是箭头函数返回一个对象,省略一个return 直接写{}会被解析成代码块
export const addItemAction = () => ({
type:ADD_ITEM,
})
export const deleteItemAction = (index) => ({
type:DELETE_ITEM,
index
})
最重要的逻辑处理数据的reducer.js
import {
CHANGE_INPUT, ADD_ITEM, DELETE_ITEM } from "./actionTypes"
const defaultState = {
inputValue:"请输入v",
list:[
"每天番茄中记时完成任务",
"每日简历投递",
"每日学习文章总结分享"
]
}
//state 是原始分数据状态,action传递过来的方法和更改的额状态
export default (state=defaultState,action) =>{
console.log (state,action)
if(action.type=== CHANGE_INPUT) {
let newState =JSON.parse(JSON.stringify(state)) //深拷贝state
newState.inputValue=action.value
console.log(newState)
return newState
}
if(action.type=== ADD_ITEM) {
let newState = JSON.parse(JSON.stringify(state))
newState.list.push(newState.inputValue) //push新的内容到列表中去
newState.inputValue = ''
console.log (newState)
return newState
}
if (action.type=== DELETE_ITEM) {
let newState = JSON.parse(JSON.stringify(state))
newState.list.splice(action.index,1)
return newState
}
return state
}
几点注意
1.reducer必须是个纯函数,
什么是纯函数???
如果函数的调用参数相同,则永远返回相同的结果。它不依赖于程序执行期间函数外部任何状态或数据的变化,必须只依赖于其输入参数。
简单的理解为返回的结果是由传入的值决定的,而不是其它的东西决定的不能调用其他数据,ajax,newDate都是不行的
2.只有store能改变自己的内容,reducer只是返回了一个数据,返回到store中,store拿到数据自己做了更新
真的要多敲几遍,把逻辑理清就好啦
码而不思则殆,学而不码也殆,多敲几遍吧~~~