我有下一个问题...
是否可以共享上下文中在特定子对象中使用的状态部分,而不必在每次整个状态更改时都渲染它,而不是在每个部分都没有渲染? (无需通过道具)
这是一个代码示例(使用props),但是我想使用“状态部分的useContext”而不在每次全局上下文更改时都呈现:
container.tsx
export const App: React.FunctionComponent<AppContextProps> = props => {
const [appState, appDispatch] = React.useReducer(reducer, initialAppState);
return (
<>
<ThemeProvider theme={theme}>
<>
<GlobalStyle />
<AppDispatch.Provider value={appDispatch}>
<FixedBottomContainer
bookForm={<BookForm />}
listContainer={
<ListContainer
books={appState.books}
discount={appState.discount}
/>
}
discountContainer={
<DiscountContainer discount={appState.discount} />
}
/>
</AppDispatch.Provider>
</>
</ThemeProvider>
</>
);
};
DiscountContainer.tsx
export const DiscountContainer: React.FunctionComponent<
DiscountContainerProps
> = ({ discount }) => {
const appDispatch = React.useContext(AppDispatch);
const handleDiscount = (event: React.ChangeEvent<HTMLInputElement>) =>
appDispatch({ type: "addDiscount", payload: event.target.value });
return (
<>
<StyledDiscountField value={discount} onChange={handleDiscount} />
</>
);
};
谢谢!
最好
答案 0 :(得分:2)
不幸的是。
反应文档说:
只要提供商的价值属性发生变化,所有作为提供商的后代的消费者都将重新呈现。
由于全局状态的一部分发生变化,整个状态就变成了另一个对象,因为我们不对现有状态进行突变,而是复制旧状态并进行更改,因此我们需要获取新状态(行动不变)。
也就是说,您仍然可以创建多个上下文。像在您的示例中一样,创建BooksContext
,DiscountContext
。
看看Kent Dodds不错的blog post关于React中的状态管理。
答案 1 :(得分:1)
您是否由于不必要的渲染而遇到某种严重的性能瓶颈?通常,这是您应该关心这种优化的唯一原因。尽量不要过早地优化React-这确实不值得。渲染的成本微乎其微,因为React本身已被很好地优化。理想情况下,您的应用编写时应确保“额外”渲染不会改变其功能。
不过,如果您坚持要这么做,可以查看React.Memo,这是一个功能组件,只有在道具更改时才重新渲染。