React的核心特征是“数据驱动视图”,也就是React 的视图会随着数据的变化而变化。
image.png

一、基于 props 的单向数据流

单向数据流,指的就是当前组件的 state 以 props 的形式流动时,只能流向组件树中比自己层级更低的组件。 比如在父-子组件这种嵌套关系中,只能由父组件传 props 给子组件,而不能反过来。

React 数据流管理方案:

  • 使用基于 Props 的单向数据流串联父子、兄弟组件;
  • 利用“发布-订阅”模式驱动 React 数据在任意组件间流动。
  • 使用 Context API 维护全局状态
  • 使用第三方数据流Redux

1、props chidren模式

  1. <Container>
  2. <Children>
  3. </Container>
  4. function Container(props){
  5. return props.children
  6. }

作用:

  • 可以根据需要控制 Chidren 是否渲染。
  • Container 可以用 React.cloneElement 强化 props (混入新的 props ),或者修改 Chidren 的子元素。

2、render props模式

  1. <Container>
  2. { (ContainerProps)=> <Children {...ContainerProps} /> }
  3. </Container>
  4. function Container(props) {
  5. const ContainerProps = {
  6. name: 'alien',
  7. mes:'let us learn react'
  8. }
  9. return props.children(ContainerProps)
  10. }

作用:

  • 根据需要控制 Chidren 渲染与否。
  • 可以将需要传给 Children 的 props 直接通过函数参数的方式传递给执行函数 children 。

3、混合模式

  1. <Container>
  2. <Children />
  3. { (ContainerProps)=> <Children {...ContainerProps} name={'haha'} /> }
  4. </Container>

这种情况需要先遍历 children ,判断 children 元素类型:

  • 针对 element 节点,通过 cloneElement 混入 props ;
  • 针对函数,直接传递参数,执行函数。
  1. const Children = (props)=> (<div>
  2. <div>hello, my name is { props.name } </div>
  3. <div> { props.mes } </div>
  4. </div>)
  5. function Container(props) {
  6. const ContainerProps = {
  7. name: 'alien',
  8. mes:'let us learn react'
  9. }
  10. return props.children.map(item=>{
  11. if(React.isValidElement(item)){ // 判断是 react elment 混入 props
  12. return React.cloneElement(item,{ ...ContainerProps },item.props.children)
  13. }else if(typeof item === 'function'){
  14. return item(ContainerProps)
  15. }else return null
  16. })
  17. }
  18. const Index = ()=>{
  19. return <Container>
  20. <Children />
  21. { (ContainerProps)=> <Children {...ContainerProps} name={'haha'} /> }
  22. </Container>
  23. }

二、知识点梳理

具体查看链接:https://www.yuque.com/linhe-8mnf5/fxyxkm/cghcta 组件通信这一块。

三、Redux

在 Redux 的整个工作过程中,数据流是严格单向的。

如果你想对数据进行修改,只有一种途径:派发 action。action 会被 reducer 读取,进而根据 action 内容的不同对数据进行修改、生成新的 state(状态),这个新的 state 会更新到 store 对象里,进而驱动视图层面做出对应的改变。

对于组件来说,任何组件都可以通过约定的方式从 store 读取到全局的状态,任何组件也都可以通过合理地派发 action 来修改全局的状态。Redux 通过提供一个统一的状态容器,使得数据能够自由而有序地在任意组件之间穿梭。

image.png

1. 使用 createStore 来完成 store 对象的创建

  1. // 引入 redux
  2. import { createStore } from 'redux'
  3. // 创建 store
  4. const store = createStore(
  5. reducer,
  6. initial_state,
  7. applyMiddleware(middleware1, middleware2, ...)
  8. );

2. reducer 的作用是将新的 state 返回给 store

  1. const reducer = (state, action) => {
  2. // 此处是各种样的 state处理逻辑
  3. return new_state
  4. }

3. action 的作用是通知 reducer “让改变发生”

  1. const action = {
  2. type: "ADD_ITEM",
  3. payload: '<li>text</li>'
  4. }

4. 派发 action,靠的是 dispatch

  1. import { createStore } from 'redux'
  2. // 创建 reducer
  3. const reducer = (state, action) => {
  4. // 此处是各种样的 state处理逻辑
  5. return new_state
  6. }
  7. // 基于 reducer 创建 state
  8. const store = createStore(reducer)
  9. // 创建一个 action,这个 action 用 “ADD_ITEM” 来标识
  10. const action = {
  11. type: "ADD_ITEM",
  12. payload: '<li>text</li>'
  13. }
  14. // 使用 dispatch 派发 action,action 会进入到 reducer 里触发对应的更新
  15. store.dispatch(action)

image.png

四、其他数据流通信实践

父-子:略
context:https://www.yuque.com/linhe-8mnf5/fxyxkm/bhg5gk#Context
发布-订阅:https://www.yuque.com/linhe-8mnf5/fxyxkm/fhe89i