реагировать на контекст с помощью компонента didupdate - PullRequest
0 голосов
/ 22 ноября 2018

Я запускаю шаблон, подобный этому, предполагается, что SearchResultsContainer смонтирован, и где-то панель поиска устанавливает ввод.

class SearchResults {
   render() {
      return(
        <ResultsContext.Consumer value={input}>
        {input => <SearchResultsContainer input=input}
        </ResultsContext.Consumer>
   )
}

class SearchResultsContainer
  componentDidUpdate() {
      //fetch data based on new input
      if (check if data is the same) {
        this.setState({
          data: fetchedData
        })
      }
  }
}

это вызовет двойную выборку всякий раз, когда новое значение контекста быловызван, потому что componentDidUpdate () сработает и установит данные.При новом вводе из контекста результатов он вызовет componentDidUpdate(), извлечет, установит данные, затем вызовет componentDidUpdate() и извлечет, затем проверит, совпадают ли данные, и остановит цикл.

Это правильный способ использования контекста?

1 Ответ

0 голосов
/ 17 января 2019

Решение, которое я использовал, заключается в передаче контекста для реквизита через компонент высокого порядка.

Я использовал этот очень полезный ответ github https://github.com/facebook/react/issues/12397#issuecomment-374004053

Результат выглядит следующим образом:my-context.js:

import React from "react";

export const MyContext = React.createContext({ foo: 'bar' });

export const withMyContext = Element => {
  return React.forwardRef((props, ref) => {
    return (
      <MyContext.Consumer>
        {context => <Element myContext={context} {...props} ref={ref} />}
      </MyContext.Consumer>
    );
  });
};

Другой компонент, который использует контекст:

import { withMyContext } from "./path/to/my-context";

class MyComponent extends Component {
 componentDidUpdate(prevProps) {
    const {myContext} = this.props
    if(myContext.foo !== prevProps.myContext.foo){
      this.doSomething()
    }
  }
}
export default withMyContext(MyComponent);

Где-то должен быть производитель контекста:

<MyContext.Provider value={{ foo: this.state.foo }}>
  <MyComponent />
</MyContext.Provider>

...