Новый React Context API запускает повторную визуализацию? - PullRequest
0 голосов
/ 12 июня 2018

Я пытался понять новый React Context API и играл с ним.Я просто хотел проверить простой случай - что все перерисовывает при обновлении данных для провайдера.

Проверьте этот небольшой пример на Codesandbox

Итак, в моем примере у меня есть компонент App, который имеет состояние вроде этого-

this.state = {
  number - A random number
  text - A static text
} 

Здесь я создаю новый контекст React, содержащий number и text из состояния, и передаю значения двум потребителям Number и Text.

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

Но на самом деле значение обновляется, но перерисовки не происходит.

Итак, мой вопрос -

  1. Обновлены до не распространенного контекстачерез обычные рендеры?Поскольку я не вижу свои журналы / изменения цвета при изменении контекста.

  2. Все ли потребители данного провайдера обновлены или нет?

1 Ответ

0 голосов
/ 12 июня 2018

Обновлены ли в контексте, не распространенном через обычные повторные показы?Поскольку я не вижу свои журналы / изменения цвета при изменении контекста.

Обновление значений контекста не вызывает повторную визуализацию для всех дочерних элементов поставщика, а только для компонентов, которые визуализируются изнутри получателя, поэтому в вашем случае, хотя числовой компонент содержит получателяКомпонент Number не рендерится, скорее это просто функция рендеринга в Consumer, и, следовательно, значение изменяется при обновлении контекста.Таким образом, он достаточно эффективен, поскольку не запускает повторные рендеры для всех своих дочерних элементов.

Обновлены ли все потребители этого провайдера или нет?

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

РЕДАКТИРОВАТЬ

Что нужно, чтобы убедитьсязаключается в том, что компоненты отображаются как дочерние компоненты компонента ContextProvider, и вы передаете ему обработчики вместо их рендеринга и обновления состояния ContextProvider, потому что это вызовет повторную визуализацию всех компонентов, которые находятся в ContextProvider

Использование Исполнителя

App.js

  render() {
    return (
      <AppContext.Provider
        value={{ ...this.state, updateNumber: this.updateNumber }}
      >
        {this.props.children}
      </AppContext.Provider>
    );
  }

index.js

class Data extends React.Component {
  render() {
    return (
      <div>
        <h1>Welcome to React</h1>
        <Number />
        <Text />
        <TestComp />
        <AppContext.Consumer>
          {({ updateNumber }) => (
            <button onClick={updateNumber}>Change Number </button>
          )}
        </AppContext.Consumer>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <App>
    <Data />
  </App>,
  rootElement
);

Меньше использования Исполнителя

App.js

class App extends Component {
  constructor() {
    super();
    this.state = {
      number: Math.random() * 100,
      text: "testing context api"
    };
  }

  updateNumber = () => {
    const randomNumber = Math.random() * 100;
    this.setState({ number: randomNumber });
  };

  render() {
    return (
      <AppContext.Provider value={this.state}>
        <div>
          <h1>Welcome to React</h1>
          <Number />
          <Text />
          <TestComp />
          <button onClick={this.updateNumber}>Change Number </button>
        </div>
      </AppContext.Provider>
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...