11.redux的简单使用

redux 的使用

http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html

1.安装redux

yarn add redux

2.创建store

整个应用只能有一个store
store/index.js

import { createStore } from 'redux';
const store = createStore(reducer);
export default store;

3.创建reducer

reducer必须是一个纯函数

  1. 固定的输入必须有固定的输出,不能有不纯粹的操作(如Data.now() Math.randonm()等)
  2. 不能对之前的状态进行任何的更改
  3. redux中遵循状态与视图一一对应的原则,状态不变视图也不变

store/reducer

let todos ={  // todos存储了共享数据
  list: [
      {
        id:1,
        title:"今天,周六,被面试题"
      },
      {
        id:2,
        title:"早起洗衣服,然后吃早饭"
      }
  ]
}
const reducer =(prevState=todos,action)=>{
  let newState = {...prevState} // 不能更改之前的状态,只能拷贝为新的状态进行更改,然后返回新的状态
  return newState
}
export default reducer

4.获取redux的状态,并渲染到dom

store.getState() 获取状态

import store from “…/…/store”

将获取到的状态存储到当前组件的状态中

state = {
    todos:[]
  }

  componentDidMount(){
    // console.log(store.getState())
    this.setState({
      todos:store.getState().todos
    })
    
  }

5. 更改redux的状态

想要更改状态,需要ActionCreators中定义action,然后将action通过store.dispatch(action)传递给Store,store在传给reducer,reducer通过纯函数的第二个参数接受到action,判断action的标记,根据标记执行不同的操作,获取到对应的新的状态。

如下,想要进行新的数据的添加

在store/actionCreators文件中

import store from "./index"
export default{
  addNewTodo(title){
    // 这个是actionCreators,作用是用来创建action
    // action是一个具有标志性信息的对象
    let action = { 
      type:"addNewTodo", //需要有标志信息
      title
    }
    store.dispatch(action) // 将具有标志性信息的action对象通过dispatch方法传递给reducer。
  }
}

在store/reducer文件中
通过reduce人纯函数的第二个参数获取到传递来的action,根据传递来的具有标志性信息的action做出判断,根据标志决定做什么事。

const reducer =(prevState=todos,action /* 通过action获取到了actionCreators传递来的action */)=>{
  let newState = {...prevState}
  switch(action.type){
    case "addNewTodo":
      newState.todos.push({id:handler.getId(newState.todos),title:action.title})
      // console.log(newState.todos)
      break;
    default:
      break;
  }
  return newState
}

const handler = {
  getId(todos){
    todos = todos.slice()
    if(todos.length === 0) return 1;
    return todos.sort((a,b)=>{
      return b.id - a.id
    })[0].id + 1
  }
}

export default reducer

store.subscribe()实时监控state状态变化,当状态变化,subscribe执行,把setState调用写在里面会执行,然后试图更新

6.store的三个重要方法

1. store.getState() 获取redux返回的状态
2. store.dispatch() 将具有标志性信息的action派发给reducer
3. store.subscribe() 订阅redux状态的改变,如果状态改变,他会执行,可以内部调用setState实现试图更新

7.组件的优化(针对组件type写错了不会弹出错误的问题)

创建文件 actionType.js

const ADD_NEW_TODO = "ADD_NEW_TODO"
const CHANGE_NEW_TODO = "CHANGE_NEW_TODO"
const DELETE_NEW_TODO = "DELETE_NEW_TODO"
export{
  ADD_NEW_TODO,
  CHANGE_NEW_TODO,
  DELETE_NEW_TODO
}

在reducer和actionCreators中引入actionType.js
使用ADD_NEW_TODO等作为action的type,这样在写错type时就会报错,便于排查错误

actionCreators中

import {ADD_NEW_TODO,CHANGE_NEW_TODO,DELETE_NEW_TODO} from "./actionType"
changeNewTodo(id){
    let action = {
      type:CHANGE_NEW_TODO,
      id
    }
    store.dispatch(action)
  },

reducer中

import {ADD_NEW_TODO,CHANGE_NEW_TODO,DELETE_NEW_TODO} from "./actionType"

case ADD_NEW_TODO:
      .........
      break;

reducer的总结

1. reducer是纯函数,传入固定的参数,得到的结果是确定的,因果一一对应。
2. 不能改写参数,需要将传入的数据进行拷贝,得到新的数据,对新数据进行操作,然后返回
3. 不能调用异步的api
4. 不允许调用不纯的方法,如Date.now()和Math.random()方法

redux的思路整理

1. redux有三部分组成 store、reducer、actionCreators

2. redux有三个重要的方法

store.getState获取redux的状态
store.subscribe订阅redux的状态改变,实时更新
store.dispath把action提交给store,store提交reducer

3. 基本流程:

  1. 获取数据:通过store.getState()获取redux的数据,处理、渲染到dom中。
  2. 更改数据:在actionCreators.js中创建actionCreator,他的作用是创建具有标志性信息的对象—action。
    这个actionCreator需要在组件中执行
const handleDelete = ()=>{
    actionCreators.deleteNewTodo(props.item.id)
  }

用他创建action,然后使用store.dispatch(action)将action传递给store。store再交给reducer。
reducer通过第一个参数接受state,通过第二个参数接受由actionCreators传来的action,
根据action中的type标准信息判断应该做什么操作(if.else或者switch…case),实际的更改state的操作是在reducer中定义的。
最终,reducer返回修改后的对象。
这时,redux的状态改变,但是组件是不知道他发生了改变的,需要调用store.subscribe方法来订阅redux状态的改变。

拆分reducer

由于每个React的redux中只能存在一个store,所以想要管理复杂的数据就需要划分reducer

1. 将reducer.js 和 actionCreators 单独放置到一个目录下,引入合并的reducer文件

import { createStore } from 'redux';
import reducer from "./reducer"
const store = createStore(reducer);
// 创建store的时候,必须借助reducer才能创建
export default store;

2. store/reducer.js 的作用是将reducer集中合并起来(需要从redux中引入combineReducer)

import {combineReducers} from "redux"

import todoList from "./todoList"

const reducer = combineReducer({
  todoList
})

export default reducer

3. 后续在组件中获取redux维护的状态

原本的状态获取方式

import store from "../store"

state = {
  todos:store.getState().todos
}

进行了reducer划分之后的获取状态方法

import store from "../store"

state = {
  todos: store.getState().todoList.todos
}

4.进行各种对应路径的修改

如引入actionCreators
import actionCreators from “…/…/store/todoList/actionCreators”

【关于eval()内部的文本进行解析(解析成代码或者计算式子…所以需要慎用)】

©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页