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拿到数据自己做了更新

真的要多敲几遍,把逻辑理清就好啦
码而不思则殆,学而不码也殆,多敲几遍吧~~~