当提供者组件父状态发生变化时,为啥不能更新子组件中的值(带有反应上下文)?

Posted

技术标签:

【中文标题】当提供者组件父状态发生变化时,为啥不能更新子组件中的值(带有反应上下文)?【英文标题】:Why can't update a value in a child component (with react context) when a provider component parent state change?当提供者组件父状态发生变化时,为什么不能更新子组件中的值(带有反应上下文)? 【发布时间】:2019-08-24 08:38:44 【问题描述】:

我正在尝试在我的项目中使用 React Context。我实现了一个提供程序组件,并且我在两个子组件中使用数据。但是当我从其中一个子组件更新 Provider 组件的状态时,另一个子组件不会使用提供程序组件中的数据重新渲染。

我正在使用 React Context 的这些特性来避免将 props 从组件传递到组件。正如我过去实施的那样

Codesandbox Example

// 父提供者

const Provider, Consumer = React.createContext()

class ShoppingCartProvider extends React.Component
 constructor(props)
            super(props)
            this.state = 
                  order: ,
                  Total: 0,

            
      

      addOrder = (key) => 
            const order = this.state.order
            let totalOrder = this.state.Total
            order[key] = order[key] + 1 || 1
            this.setState(order)
            totalOrder = totalOrder + 1
            this.setState(Total: totalOrder)

      
      render()
            return(
                  <Provider value=
                        order: this.state.order,
                        addOrder: this.addOrder,
                        totalOrder: this.state.Total
                  >
                  <div>this.props.children</div>
                  </Provider>     
            )
      


export ShoppingCartProvider, Consumer as ShoppingCartConsumer

//改变父状态的子

import React, useContext  from 'react';

const ItemProducto = props =>
      const product = props

      const addOrder = useContext(ShoppingCartConsumer)

      return <Grid item>
                 <div css=botonAdd
                   onClick=()=>
                        addOrder(product._id)
                  >Add</div>
             </Grid>





export default ItemProducto

//这个在父组件状态改变时不会重新渲染



import React, useContext, useEffect, useState from 'react';

const Header = props =>      

      const totalOrder = useContext(ShoppingCartConsumer)
      const [count, setcount] = useState(totalOrder)

      useEffect(()=>
            setcount(totalOrder)
      )
      return (
           <div>                                                                
              <Grid item  css=numeroDinero>count</Grid>                                                              
           </div> 

      )



export default Header

当 ItemProducto 子项更改 Total 状态属性时,我希望在 Header 子项中重新渲染。

【问题讨论】:

请你在codesandbox上重现这个,我有兴趣看看。 只需在示例代码框中分享一个链接 【参考方案1】:

您的代码中的所有内容都会检出,除了一个。 useContext() 期望实际上下文作为参数而不是消费者。在您的情况下,您通过这样做传递了消费者:export ..., Consumer as ShoppingCartConsumer

您需要做的就是解决这个问题: 在ShoppingCartContext更改:

const Provider, Consumer = React.createContext()

const ShoppingCartContext = React.createContext();.

在你的render:

render() 
    return (
      <ShoppingCartContext.Provider
        value=
          order: this.state.order,
          addOrder: this.addOrder,
          totalOrder: this.state.Total
        
      >
        <div>this.props.children</div>
      </ShoppingCartContext.Provider>
    );
  

然后将您的导出更改为:export ShoppingCartProvider, ShoppingCartContext ;

相应地修改HeaderItemProducto中的导入,不要忘记将ShoppingCartContext传递给它们各自的useContext()s。

有关useContext 的更多信息,请参阅here

【讨论】:

以上是关于当提供者组件父状态发生变化时,为啥不能更新子组件中的值(带有反应上下文)?的主要内容,如果未能解决你的问题,请参考以下文章

在 React 中通过更改父级的道具来更新子组件

React.memo()、useCallback()、useMemo() 区别及基本使用

当 vuex 商店的值发生变化时,如何更新组件中的状态?

React Native - 从父组件重新渲染子组件

useMemo, useCallback, useEffect 三者区别

react父组件传入的属性没有让子组件收到的prop变化