Как получить доступ к части состояния контекста, не отображая каждый раз глобальные изменения? - PullRequest
0 голосов
/ 11 июня 2019

У меня следующий вопрос ...

Можно ли было бы разделить часть состояния, которая находится в контексте, потребляемую конкретным дочерним элементом, без его рендеринга каждый раз, когда изменяется полное состояние, а неэта часть?(Не пропуская его через реквизиты)

И это пример кода (с использованием реквизита), но вместо этого я хочу использовать «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} />
    </>
  );
};

Заранее спасибо!

Best

Ответы [ 2 ]

2 голосов
/ 11 июня 2019

К сожалению, нет.

В React Docs сказано:

Все потребители, являющиеся потомками провайдера, будут выполнять рендеринг при каждом изменении значения провайдера.

Как только часть глобального состояния изменяется, все состояние становится другим объектом, потому что мы не изменяем существующее состояние, а копируем старое и вносим изменения, нам нужно получить новое (неизменность в действии).

Тем не менее, вы все еще можете создавать несколько контекстов.Как и в вашем примере, создайте BooksContext, DiscountContext.

Посмотрите на приятное сообщение в блоге Кент Доддс об управлении состоянием в React.

1 голос
/ 11 июня 2019

Вы сталкиваетесь с каким-то серьезным узким местом производительности, вызванным ненужными рендерами? Как правило, это единственная причина, по которой вы должны заботиться о такой оптимизации. Старайтесь не преждевременно оптимизировать React, когда вам это не нужно - это действительно того не стоит. Стоимость рендеринга ничтожна, потому что сам React так хорошо оптимизирован. И в идеале ваше приложение написано так, что «дополнительные» рендеры не изменят как оно функционирует.

Однако, если вы настаиваете, вы можете заглянуть в React.Memo , который является функциональным компонентом, который перерисовывается только при смене реквизита.

...