以下问题与React Context文档中的以下部分相关:
免责声明:对以下所有背景信息深表歉意。它提供了背景信息,希望对以后的访问者有帮助。
我们所知道的
themes.dark
(一个包含两个属性的对象:foreground
和background
)Providers
上方没有Consumer
时才使用默认值Provider
)中存在App
Provider
(App
)作为{em> context值 state
Provider
提供的值的结构和类型设置为默认的 context值(避免Consumers
混淆)是很聪明的state
)中的App
拥有与默认 context值相同的格式的对象:themes.light
Consumer
读取上下文时,它将读取App
的状态App
)state
,而不必将其传递给每个组件在中间App
)中的状态更改时,它会重新呈现,并为Consumer
提供新的状态值Consumer
通过 context state
。
state
(toggleTheme
)的功能作为普通prop
传递到组件树中/ li>
context
仅 包含读取 state
Consumer
的子元素作为普通setState
传递prop
函数,在Provider
中设置状态{em> ,向下遍历所有中间组件,然后进入Consumer
state
)中设置App
会导致自身的重新呈现,这会导致Provider
的重新呈现通过 context App
state
值向下传递到其Consumer
Consumer
总是通过 context App
的状态。
state
作为上下文值提供给孩子Consumer
state
由某个孩子更新Provider
看到 context值(App
的{{1}})已更改,并使用新价值state
函数,在Consumer
中设置{em> {1>} {em} li>
state
来设置Consumer
问题
我们从the docs知道:
每个Context对象都带有一个提供方React组件,该组件允许 消耗组件以订阅上下文更改。...
作为提供者后代的所有使用者将重新呈现 只要提供商的价值支柱发生变化。
setState
中使用普通变量作为上下文值。从上面的引用中我们知道,更改它会导致prop
重新呈现。那么,为什么要使用state
作为 context 值呢?与仅在App
中使用任何普通变量相比,这样做有什么好处?Provider
。为什么链接2合并了在state
内更新App
的功能?我们不能仅仅将其作为单独的state
函数,它通过 context 传递给具有两个属性(一个是state
)的对象中的state
另一个是独立功能来更新setState
)?答案 0 :(得分:2)
让我们假设我们在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
}} />
)
}
}
因此,他们在状态中存储函数的示例是确保所提供的整个值不会从一个渲染更改为另一个。
答案 1 :(得分:0)
假设我们使用 App 中的一个普通变量作为上下文值。我们从上面的引用中知道,更改它会导致 Provider 重新渲染。那么,我们为什么要使用状态作为上下文值呢?与仅在 App 中使用任何普通变量相比,这样做有什么好处?
当你使用 state 并更新它时——不管你是否使用提供者——所有的提供者和它下面的组件都会更新。那是在官方 React Context 文档下,是错误的。这意味着更改提供者值根本不会调用使用者更新。
您可以通过创建一个带有状态的单独组件(不会在提供者内部)来验证这一点,并将该状态变量分配给提供者。因此,当组件状态发生变化时,状态中的值发生变化,提供者应该注意到这一点并更新消费者。它没有这样做。
为了更新消费者下的组件,不幸的是,您必须手动进行。除非您打算更新提供程序下的所有内容。
截至 2021 年 4 月 21 日,在 React 17.0.2 下这是真的——提供者值的变化没有被监控,消费者也没有被更新。除非您将所有提供程序都放在带有状态的组件中,但更改其状态会强制更新提供程序下的所有组件。很遗憾。