以下问题与React Context文档中的以下部分相关:
Dynamic Context
Updating Context from a Nested Component
免责声明:对以下所有背景信息深表歉意。它提供了上下文,希望对将来的访问者有所帮助。
我们所知道的
链接1
(默认)上下文值设置为themes.dark
(包含两个属性的对象:foreground
和background
)
仅当组件树中Providers
上方没有Consumer
时才使用默认值
在这种情况下,顶级组件(Provider
)中存在App
此Provider
(App
)向下传递其自己的state
作为上下文值
保持Provider
提供的值在结构和类型上与默认上下文值相同是很聪明的(避免Consumers
混淆)
因此,顶级组件(state
)中的App
拥有与默认上下文值相同格式的对象:themes.light
以上结论:当Consumer
读取上下文时,它读取App
的状态
换句话说,我们在这里使用上下文在组件树中深入父级(App
)state
,而不必通过中间的每个组件
当顶级组件(App
)中的状态更改时,它会重新呈现,并为Consumer
提供一个新的state值
这样,Consumer
通过上下文读取父级的state
...
继续,我们在链接1中看到将设置state
(toggleTheme
)的函数作为常规prop
传递到组件树中
因此,在链接1中,context
仅包含读取state
的对象。
我们可以通过将Consumer
函数作为普通setState
从prop
的子级传递到所有中间组件,再传递到Provider
来在Consumer
中设置状态
在顶级组件(state
)中设置App
会导致自身的重新呈现,这会导致Provider
的重新呈现,然后传递新的App
state
通过上下文将其值降至Consumer
这样,Consumer
总是通过上下文知道App
的状态
总之,流程为:
父级state
作为上下文值提供给子级Consumer
父母的state
由某个孩子更新
家长退还Provider
看到上下文值(App
的state
)已更改,并用新值重新呈现其所有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/