redux的使用流程

redux

React只是DOM的一个抽象层

Web应用是一个状态机,视图与状态是一一对应的

所有的状态,保存在一个对象里面(唯一数据源)

需要使用redux的项目

  • 用户的使用方式复杂
  • 不同身份的用户有不同的使用方式(比如普通用户和管理员)
  • 多个用户之间可以协作
  • 与服务器大量交互,或者使用了WebSocket
  • View要从多个来源获取数据

从组件层面考虑,什么样子的需要redux:

  • 某个组件的状态,需要共享
  • 某个状态需要在任何地方都可以拿到
  • 一个组件需要改变全局状态
  • 一个组件需要改变另一个组件的状态
redux有四个组成部分

store:用来存储数据

reducer:真正的来管理数据

actionCreators:创建action,交由reducer处理

view:用来使用数据

redux的流程

1)store通过reducer创建了初始状态
2)view通过store.getState()获取到了store中保存的state挂载在了自己的状态上
3)用户产生了操作,调用了actions 的方法
4)actions的方法被调用,创建了带有标示性信息的action
5)actions内部通过调用store.dispatch方法将标志性的action发送到了reducer中
6)reducer接收到action并根据标识信息判断之后返回了新的state
7)store的state被reducer更改为新state的时候,store.subscribe方法里的回调函数会执行,此时就可以通知view去重新获取state

例如创建如下案例

image-20200907210859121

store通过reducer创建了初始状态,在reducer中定义一个数组

reducer.js

let state = {
    list: [
        { id: 1, title: "星期一", isFinished: true },
        { id: 2, title: "星期二", isFinished: false }
    ]
}
const reducer = (prevState = state, action) => {
    //让上一条数据默认为state
    let newState = { ...prevState }
    return newState
}

view通过store.getState()获取到了store中保存的state挂载在了自己的状态上

在TodoContent组件中展示数据

const LiItem = props => {
    return (
        <li key={props.item.id} style={{textDecoration:props.item.isFinished?'line-through':'none'}}>
            {props.item.title}
        </li>
    )
}
export default class TodoContent extends Component {
    constructor() {
        super()
        //声明一条数据
        this.state = {
            list: []
        }
    }
    setList = () => {
        //从store的getState()方法中获取到list并更改state中的list数据
        this.setState({
            // Store对象包含所有数据。如果想得到某个时点的数据,就要对 Store 生成快照。当前时刻的 State,可以通过store.getState()拿到。
            list: store.getState().list
        })
    }
    componentDidMount() {
        this.setList()
        //Store 允许使用store.subscribe方法设置监听函数,一旦 State 发生变化,就自动执行这个函数。当state的数据改变时,就去执行setList,由此state的数据也会改变,render也会重新渲染
        store.subscribe(() => {
            this.setList()
        })
    }

    renderList = () => {
        let {list} =this.state
        return list.map(item => {
            return <LiItem key={item.id} item={item} />
        })
    }
    render() {
        return (
            <ul>
                {
                    this.renderList()
                }
            </ul>
        )
    }
}

当input框输入文本时,按下键盘下的Enter,列表会增加一条

也就是当用户产生了操作,调用了actions 的方法

组件TodoInput

import actionCreators from "../../store/actionCreators"
export default class TodoInput extends Component {
    handleKey=e=>{
        if(e.keyCode==13){
            // 当按下Enter键时,触发actionCreators下的addNewTode
            actionCreators.addNewTode(e.target.value)
            e.target.value=""
        }
      
    }
    render() {
        return (
            <input placeholder="请输入内容" onKeyUp={this.handleKey}/>
        )
    }
}

actions的方法被调用,创建了带有标示性信息的action
actions内部通过调用store.dispatch方法将标志性的action发送到了reducer中

actionCreators.js

const actionCreators = {
    addNewTodo(title){
        //需要定义一个具有特殊标识的action对象
        let action = {
            type:ADD_NEW_TODO,
            title
        }
        //需要将action对象派发给reducer
        store.dispatch(action)
    }
}

export default actionCreators

reducer接收到action并根据标识信息判断之后返回了新的state,store.subscribe方法里的回调函数会执行,此时就可以通知view去重新获取state

reducer.js

const reducer = (prevState = state, action) => {
    let newState = { ...prevState }
    return newState
}
请用今天的努力,让明天没有遗憾。
原文地址:https://www.cnblogs.com/cupid10/p/15617669.html