React从0开始(五):基础组件间通信(下)

308 阅读4分钟

这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战

上一篇文章学习了父-子子-父以及兄弟组件间通过Props以及发布订阅模式的通信,这一篇文章我们来学习其他部分的组件间通信的方法

一、Context

这里写的是新版的Context,新版Context解决了一个问题:旧版Context在修改上下文时,会因为shouldComponentUpdate返回false导致子组件或孙子组件无法正常更新视图。新版则解决了这一个问题。Context避免了手动添加Props,让数据进行层层传递的繁杂问题。Context主要用于很多不同层级的组件间相同数据的使用的场景.

1.Context API的组成

Context有三个重要的组成部分:Context对象Provider提供者Consumer消费者Provider可以将自身的数据提供给Consumer,此外Consumer还能够及时地同步Provider中数据的更新,跨越层级,组件树内皆可Consumer

2.React.createContext

通过使用React.createContext方法可以创建出一个Context对象

const NewContext = React.createContext('New Context');

3.获取ProviderConsumer

在上一步创建出Context对象以后,我们可以从Context对象中获取到ProviderConsumer

const {Provider,Consumer} = NewContext

4.Provider的使用

Provider作为提供者,只需要将Provider作为一个组件,将需要提供的参数保存在一个对象中作为value属性即可共享,并将Provider组件包裹住需要获取该提供者数据的组件,那么被包裹住的组件均为Consumer

//父组件进行Provider
<Provider value={ {content:this.state.content} }>
    <Children />
</Provider>

5.Consumer的使用

//子组件使用Provider中的content
<Consumer>
    {
        value => {
            return <div>{value.content}</div>
        }
    }
</Consumer>

效果图:

image.png

6.总结:Context API使用流程

  1. 通过React.createContext创建Context对象,并从Context对象中获取到ProviderConsumer
  2. 确定好需要传递数据的组件,用Provider在该组件中包裹住子组件,随后将需要传递的数据用对象保存,最后以value属性传给Provider则完成提供数据步骤
  3. 在子组件中使用Consumer包裹住即将获取数据的逻辑代码,通过以value为参数的函数进行处理

二、Redux

先来了解一下Redux的描述:ReduxJavascript的状态容器,它提供可预测的状态管理。也就是说,Redux不仅仅适用于React,还适用于AngularVue等的状态管理。

1.Redux工作原理

通过下图即可了解Redux的工作原理

image.png

2.Reudx的组成部分

  1. Store:可以理解为仓库,用于存储数据
  2. Reducer:对变化进行分发与处理,最终将新的数据返回给store
  3. Action:用于对数据变化的描述

View来源于Store,若发生变化,则会进行变化的派发(Action),随后Reducer处理变化,返回新的Store并响应到视图上

工作流如下:Redux工作过程中,数据流是严格单向的

image.png

image.png

3.Redux初体验

使用前注意事项:

  1. action需要进行store.dispatch派发
  2. dispatch时传入的必须是对象,且必须要有type属性
  3. store.subscribe(()=>{})相当于是对store的监听,若store有变化则触发回调

代码如下:

//父组件
render() {
    Store.subscribe(()=>{
        this.setState({
            content:Store.getState().content
        })
    })
    return (
        <div>
            <div>{this.state.content}</div>
            <Children />
            <NewChildren />
        </div>
    )
}
//A组件(Children)
render() {
    return (
        <div>
            <button onClick={ ()=>{ Store.dispatch( { type:"fromA" } ) } }>作为A修改Store</button>
        </div>
    )
}
//B组件(NewChildren)
render() {
    return (
        <div>
            <button onClick={ ()=>{ Store.dispatch( { type:"fromB" } ) } }>作为B修改Store</button>
        </div>
    )
}

使用效果如下:

image.png

image.png

image.png

4.使用总结

  1. 先对Reducer(state,action)进行定义,定义state的初始状态,以及利用switch判断action.type所处情况编写逻辑,返回对应的新state对象
  2. 写好Reducer后,就可以进行Store的创建:const Store = React.createStore(Reducer),并导出创建好的Store
  3. 这个时候就可以在使用Redux的组件中引入创建好的Store了,在指定事件触发后就可以根据操作进行action的派发(dispatch)了,store.dispatch( {type:""} )(记住,这里传入的对象其实就是action,对action的处理逻辑早就已经写在了Reduce里)
  4. 派发完成以后,store中的state得到了更新,就可以通过store.getState()来获取state对象。(另外,store.subscribestore更新时会触发,可以通过这个函数的回调进行组件内状态的更改以便及时更改视图

简而言之,就是编写逻辑到Reducer利用Reducer创建Store利用Store派发触发更新

文字说多了还是有点乱,下面放一张我整理的图,如果有误可以评论我修改一下,感谢。

image.png