以下问题与React Context文档中的以下部分相关:


Dynamic Context
Updating Context from a Nested Component


免责声明:对以下所有背景信息深表歉意。它提供了上下文,希望对将来的访问者有所帮助。



我们所知道的


链接1


(默认)上下文值设置为themes.dark(包含两个属性的对象:foregroundbackground
仅当组件树中Providers上方没有Consumer时才使用默认值
在这种情况下,顶级组件(Provider)中存在App
ProviderApp)向下传递其自己的state作为上下文值
保持Provider提供的值在结构和类型上与默认上下文值相同是很聪明的(避免Consumers混淆)
因此,顶级组件(state)中的App拥有与默认上下文值相同格式的对象:themes.light
以上结论:当Consumer读取上下文时,它读取App的状态
换句话说,我们在这里使用上下文在组件树中深入父级(Appstate,而不必通过中间的每个组件
当顶级组件(App)中的状态更改时,它会重新呈现,并为Consumer提供一个新的state值
这样,Consumer通过上下文读取父级的state
...
继续,我们在链接1中看到将设置statetoggleTheme)的函数作为常规prop传递到组件树中
因此,在链接1中,context仅包含读取state的对象。
我们可以通过将Consumer函数作为普通setStateprop的子级传递到所有中间组件,再传递到Provider来在Consumer中设置状态
在顶级组件(state)中设置App会导致自身的重新呈现,这会导致Provider的重新呈现,然后传递新的App state通过上下文将其值降至Consumer
这样,Consumer总是通过上下文知道App的状态
总之,流程为:


父级state作为上下文值提供给子级Consumer
父母的state由某个孩子更新
家长退还
Provider看到上下文值(Appstate)已更改,并用新值重新呈现其所有Consumer


连结2


在链接2中,通过在上下文中传递state函数,在Consumer中设置setState
这与链接1不同,在链接1中,我们依靠普通的prop设置state





问题

the docs我们知道:


  每个Context对象都带有一个Provider React组件,该组件允许
  消耗组件以订阅上下文更改。
  
  作为提供者的后代的所有消费者将重新呈现
  只要提供商的价值支柱发生变化。



假设我们在App中使用普通变量作为上下文值。从上面的引用中我们知道,更改它会导致Provider重新呈现。那么,为什么要使用state作为上下文值呢?与仅在App中使用任何普通变量相比,这样做有什么好处?
以上两种方法都允许我们更新state。为什么链接2合并了在state自身内部更新state的功能?我们不仅可以将其作为单独的setState函数,还可以通过上下文将其传递给具有两个属性的对象(一个是Consumer,另一个是用于更新state的独立函数)的对象中的state。 ?

最佳答案

假设我们在App中使用普通变量作为上下文值。从上面的引用我们知道,更改它会导致提供程序重新渲染。那么,为什么要麻烦使用状态作为上下文值呢?与仅在App中使用任何普通变量相比,这样做有什么好处?


的确,当使用更改后的值重新渲染提供程序时,所有关心上下文的后代都将重新渲染。但是您首先需要使提供者重新呈现的内容。当App的状态或其属性发生更改时(或当您调用forceUpdate而不执行此操作时),就会发生这种情况。大概,这是在应用程序的顶部,因此没有任何道具进入,这意味着您将使用状态来使其重新呈现。


  上面的两种方法都允许我们更新状态。为什么链接2合并了在状态本身内部更新状态的功能?我们是否可以不仅仅将其作为单独的setState函数,该函数通过上下文传递给具有两个属性(一个是状态,另一个是用于更新状态的独立函数)的对象中的上下文?


当决定是否由于上下文的变化而重传后代时,react基本上会在旧值和新值之间做一个===。这非常快,并且可以与React对于不可变数据的偏好很好地配合,但是当使用对象作为您的值时,需要注意不要在每个渲染器上都制作新对象。例如,如果App正在执行以下操作,则它将在每次渲染时创建一个全新的对象,从而也将强制所有上下文使用者重新渲染:

class App extends Component {
  state = {
    data: {
      hello: 'world',
    }
  }

  updateData() {
    // some function for updating the state
  }

  render() {
    return (
      <MyContext.Provider value={{
        data: this.state.data,
        updateData: this.updateData
      }} />
    )
  }
}


因此,他们在状态中存储函数的示例是确保所提供的整个值不会从一个渲染变为另一个。

关于javascript - react :改变消费者的环境,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55364544/

10-15 14:58