如何在不每次全局更改都呈现的情况下访问上下文状态的一部分?

时间:2019-06-11 15:44:58

标签: reactjs typescript react-hooks

我有下一个问题...

是否可以共享上下文中在特定子对象中使用的状态部分,而不必在每次整个状态更改时都渲染它,而不是在每个部分都没有渲染? (无需通过道具)

这是一个代码示例(使用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} />
    </>
  );
};

谢谢!

最好

2 个答案:

答案 0 :(得分:2)

不幸的是。

反应文档说:

  

只要提供商的价值属性发生变化,所有作为提供商的后代的消费者都将重新呈现。

由于全局状态的一部分发生变化,整个状态就变成了另一个对象,因为我们不对现有状态进行突变,而是复制旧状态并进行更改,因此我们需要获取新状态(行动不变)。

也就是说,您仍然可以创建多个上下文。像在您的示例中一样,创建BooksContextDiscountContext

看看Kent Dodds不错的blog post关于React中的状态管理。

答案 1 :(得分:1)

您是否由于不必要的渲染而遇到某种严重的性能瓶颈?通常,这是您应该关心这种优化的唯一原因。尽量不要过早地优化React-这确实不值得。渲染的成本微乎其微,因为React本身已被很好地优化。理想情况下,您的应用编写时应确保“额外”渲染不会改变其功能。

不过,如果您坚持要这么做,可以查看React.Memo,这是一个功能组件,只有在道具更改时才重新渲染。