gpt4 book ai didi

reactjs - 是否可以在多个组件上使用相同的

转载 作者:行者123 更新时间:2023-12-04 12:17:06 25 4
gpt4 key购买 nike

我知道我可以用我的 <Context.Provider> 包裹 HOC并在所有子组件中使用它。

我想在两个单独的组件中使用上下文,但它们嵌套在某个深处,并且它们最接近的父级位于应用程序根的某个位置。我不想为(几乎)所有组件提供上下文,所以我想知道是否可以只包装这两个组件?

我尝试这样做,但只有第一个组件获得上下文。

应用程序结构如下所示:

<App>
<A1>
<A2>
<MyContext.Provider>
<Consumer1/>
</MyContext.Provider>
</A2>
</A1>
<B1>
<B2>
<MyContext.Provider>
<Consumer2/>
</MyContext.Provider>
</B2>
</B1>
</App>


编辑:我错误地认为包装根组件将使上下文更改时重新渲染所有子组件。只有消费者会重新渲染,所以包装根组件完全没问题。

最佳答案

如果您想拥有一个在应用程序的多个部分之间共享的单个值,那么在某种形式中,您需要将该值向上移动到需要使用该值的那些的共同祖先组件。正如您在评论中提到的,您的问题是性能问题之一,并且尽量不重新渲染所有内容。拥有两个提供者并没有真正帮助解决这个问题,因为仍然需要一些组件来确保两个提供者提供相同的值(value)。因此该组件最终需要成为两个提供者的共同祖先。

相反,您可以使用 shouldComponentUpdate(对于类组件)或 React.memo(对于功能组件)来阻止重新渲染过程沿着组件树向下工作。使用 Context.Consumer 的深层后代仍然会重新渲染,因此您可以跳过树的中间部分。下面是一个例子(注意中间组件上 React.memo 的使用):

const Context = React.createContext(undefined);

const useCountRenders = (name) => {
const count = React.useRef(0);
React.useEffect(() => {
count.current++;
console.log(name, count.current);
});
}

const App = () => {
const [val, setVal] = React.useState(1);
useCountRenders('App');

React.useEffect(() => {
setTimeout(() => {
console.log('updating app');
setVal(val => val + 1)
}, 1000);
}, [])

return (
<Context.Provider value={val}>
<IntermediateComponent />
</Context.Provider>
);
}

const IntermediateComponent = React.memo((props) => {
useCountRenders('intermediate');
return (
<div>
<Consumer name="first consumer"/>
<UnrelatedComponent/>
<Consumer name="second consumer"/>
</div>
);
})

const Consumer = (props) => {
useCountRenders(props.name);
return (
<Context.Consumer>
{val => {
console.log('running consumer child', props.name);
return <div>consuming {val}</div>
}}
</Context.Consumer>
)
}

const UnrelatedComponent = (props) => {
useCountRenders('unrelated');
return props.children || null;
}


ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.2/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.2/umd/react-dom.development.js"></script>
<div id="root"></div>


运行上述代码时,请检查日志以查看哪些组件重新渲染。在第一遍时,所有内容都会呈现,但在应用状态更改后的一秒钟后,只有应用会重新呈现。 IntermediateComponent、UnrelatedComponent 甚至 Consumer 都不会重新渲染。 Context.Consumer 中的函数会重新运行,并且该函数返回的任何内容(在本例中只是一个 div)都将重新渲染。

关于reactjs - 是否可以在多个组件上使用相同的 <Context.Provider>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58474027/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com