美文网首页
react redux 基础

react redux 基础

作者: 苍老师的眼泪 | 来源:发表于2022-08-06 08:38 被阅读0次

    安装:

    yarn add redux react-redux
    yarn add redux-devtools --dev
    

    三大原则:

    • 单一数据源:整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。
    • State 是只读的:唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。
    • 使用纯函数来执行修改:为了描述 action 如何改变 state tree ,你需要编写 reducers。

    使用:

    1. 定义 store

    • 编写 reducer :一个 reducer 就是一个函数,跟 react 里面的 useReducer hook 里的 reducer 其实是一样的,都是接收第一个参数为 state, 第二个参数为 action, 最后返回一个新的 state。action 参数就是描述如何改变 store 里面的数据的对象,第一个参数 state 是 store 里面的整个 state 或 state 的一部分,reducer 函数根据不同的 action 对象对 state 进行处理,最后返回一个经过处理后的 state, 以此表示对整个 state 或 state 的一部分 的修改。react 强调 reducer 永远不要做以下操作:
      (1) 修改传入参数;
      (2) 执行有副作用的操作,如 API 请求和路由跳转;
      (3) 调用非纯函数,如 Date.now() 或 Math.random()。
      并且遵循: 只要传入参数相同,返回计算得到的下一个 state 就一定相同。没有特殊情况、没有副作用,没有 API 请求、没有变量修改,单纯执行计算。
      技巧:因为 reducer 必须返回一个 state(遇到未知的 action 时,一定要返回旧的 state),因此 reducer 的默认参数使用 es6 的默认 state 将精简代码。
      总结:因为一个应用的 state 可能很大,由几个部分的功能组成,此时可以根据功能将 state 拆解为多个 reducer 处理,每个 reducer 必须返回一个 state, 由于返回的 state 的结构是具体的,多个 reducer 返回的 state 的组合就是整个应用的 state,无需再另外定义应用的 state 结构,它已经由各个 reducer 所返回的 state 定义。

    • 将多个 reducer 组合起来
      定义好所有需要的 reducer 后,就应该将它们组合起来,形成一个主 reducer,例如一个应用的主 reducer 可能类似于这样:

    function todoApp(state = {}, action) {
      return {
        visibilityFilter: visibilityFilter(state.visibilityFilter, action),
        todos: todos(state.todos, action)
      }
    }
    

    它表示整个应用的 state 对象由 visibilityFilter 和 todos 部分组成(当然实际的应用可能远远不止这么简单)。reducer visibilityFilter 和 reducer todos 的调用分别返回了各自的部分。这种应用的 state 属性名和响应的 reducer 函数名一致时,可以借助于 react-redux 的 combineReducers 简化代码:

    const todoApp = combineReducers({
      todos,
      visibilityFilter
    })
    

    最终,todoApp就是我们整个应用的 state。

    2. 将 store 与 react 组件关联起来

    • 根据 state 创建出整个应用是 store,将其作用在应用的根组件上:
    let store = createStore(todoApp)
    
    <Provider store={store}>
        <App />
    </Provider>
    
    • 为了避免不必要的重复渲染,可以将应用分为:容器组件展示组件
      (1)展示组件:这些组件只定义外观并不关心数据来源和如何改变。传入什么就渲染什么。如果你把代码从 Redux 迁移到别的架构,这些组件可以不做任何改动直接使用。它们并不依赖于 Redux。
      (2)容器组件:负责把展示组件连接到 Redux,具体的方法就是调用 react-redux 的 connect 函数,它主要接收两个参数:
      I: 第一个参数为一个函数,用于定义怎么将整个应用的 state 映射为展示组件的 props,这个函数接收两个参数,第一个是整个应用的 state, 第二个是该展示组件自身的 props,返回一个对象,该对象的根属性将成为展示组件的 props (数据)属性。
      II: 第二个参数也是一个函数,用于定义怎么将整个应用的 dispatch 调用成为展示组件的 props,这个函数接收两个参数,第一个是整个应用的 store 的 dispatch 方法。
      第二个是展示组件自己的props, 返回一个对象,该对象的根属性将成为展示组件的 props (方法)属性。
      connect 返回一个函数,这个函数以展示组件作为参数调用后返回一个新的组件,这个组件就是展示组件连接到 Redux 之后的组件。

    其它

    1. 技术上讲,容器组件就是使用 store.subscribe() 从 Redux state 树中读取部分数据,并通过 props 来把这些数据提供给要渲染的组件。你可以手工来开发容器组件,但建议使用 React Redux 库的 connect() 方法来生成,这个方法做了性能优化来避免很多不必要的重复渲染。使用 connect() 前,需要先定义 mapStateToProps 这个函数来指定如何把当前 Redux store state 映射到展示组件的 props 中。
    2. 除了读取 state,容器组件还能分发 action。类似的方式,可以定义 mapDispatchToProps() 方法接收 dispatch() 方法并返回期望注入到展示组件的 props 中的回调方法。
    实操总结:
    • 有时候卡了,要关闭 devServer 重新 yarn start
    • 所有的 action 不管简单与复杂,都要放在相对统一的地方
    • 关于 connet 函数第二个参数:要不就不传(传null),所有的展示组件里面直接调用 props.dispatch 完成action; 要不就全部用 mapDispatchToProps 返回的对象属性,如果传入了 mapDispatchToProps, 则展示组件的 props.dispatch 将为 undefined,否则会暴露 props.dispatch 方法。
    • 如果有触发一个 action,每个 action 匹配多个 reducer 的 action 的 "type",则所有匹配的 action 都会触发

    redux api:

    import { createStore } from 'redux'
    import { Provider } from 'react-redux'
    
    import { combineReducers } from 'redux'
    
    import { connect } from 'react-redux'
    
    import { createStore, applyMiddleware } from 'redux'
    import thunkMiddleware from 'redux-thunk'
    

    相关文章

      网友评论

          本文标题:react redux 基础

          本文链接:https://www.haomeiwen.com/subject/bfrbwrtx.html