API контекста версии 16.6.0 или выше не работает, когда дочерний элемент используется в компоненте, который предоставляет контекст - PullRequest
0 голосов
/ 04 января 2019

Я использую новый контекстный API реакции (v16.6.0 или выше), объявив public static contextType внутри компонента, который использует контекст.Это работает нормально, пока компонент, который объявляет Provider, напрямую не использует компонент, который использует контекст в своем методе render().

Пример:

ParentWithContext

Это компонент, который создает и предоставляет контекст.

export const SomeContext = React.createContext({
  someValue: false
});

export default class ParentWithContext extends Component {
  public render(){
    const contextValue = {someValue: true};
    return (
      <SomeContext.Provider value={contextValue}>
        <ChildOne />
        {this.props.children}
      </SomeContext.Provider>
    );
  }
}

Обратите внимание, что этот компонент использует компонент ChildOne (см. Ниже)в его методе render().

ChildOne и ChildTwo

Эти два компонента просто используют вышеуказанный контекст и отображают его.

export default class ChildOne extends Component {
  public static contextType = SomeContext;
  public render(){
    return (
      <div>
        {`Context of ChildOne: ${this.context.someValue}`}
      </div>
    );
  }
}

export default class ChildTwo extends Component {
  public static contextType = SomeContext;
  public render(){
    return (
      <div>
        {`Context of ChildTwo: ${this.context.someValue}`}
      </div>
    );
  }
}

index.tsx

class App extends Component {

  render() {
    return (
      <ParentWithContext>
        <ChildTwo />
        <ChildOne />
      </ParentWithContext>
    );
  }
}

Запуск этого примера приведет к следующим строкам:

Context of ChildOne: undefined
Context of ChildTwo: true
Context of ChildOne: undefined

Так что ChildTwo, кажется, получает правильную информациюот this.context, в то время как ChildOne ничего не получает.

Теперь возникает странная часть (для меня): когда вы удаляете <ChildOne/> из ParentWithContext, он неожиданно работает как для ChildOne, так и ChildTwo

Новый ParentWithContext

export default class ParentWithContext extends Component {
  public render(){
    const contextValue = {someValue: true};
    return (
      <SomeContext.Provider value={contextValue}>
        {this.props.children}
      </SomeContext.Provider>
    );
  }
}

Новый вывод HTML

Context of ChildTwo: true
Context of ChildOne: true

Рабочий код

Вопрос

Почему не работает API контекста (> = v16.6) (использование static contextType), когда компонент Provider напрямую использует дочерний компонент, который использует контекст в своей функции render()?Это ошибка или известное ограничение?Я что-то пропустил?

Дополнительная информация

Использование <SomeContext.Consumer> будет работать должным образом.

export default class ChildOne extends Component {
  public render(){
    return (
      <SomeContext.Consumer>
        {context =>
          <div>
          {`Context of ChildOne: ${context.someValue}`}
          </div>
        }
      </SomeContext.Consumer>
    );
  }
}

Конечно, это не решение этой проблемы, но может бытьполезная информация.

1 Ответ

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

Я создавал проблему на реагирующем github , чтобы выяснить, что это была не ошибка реагирования, а проблема Javascript / Typescript.

Сводка

Неправильный порядок импорта вызвал «ошибку».Поскольку ChildOne было импортировано (в ParentWithContext) до объявления контекста, SomeContext было на самом деле undefined, когда оно было импортировано в ChildOne.

import ChildOne from "./ChildOne";

export const SomeContext = React.createContext({
  someValue: false
});

Таким образом, одно решение было бычтобы обменять этих двух государственных деятелей

export const SomeContext = React.createContext({
  someValue: false
});

import ChildOne from "./ChildOne";

Или просто (и очиститель ИМХО) извлечь контекст в его собственный файл.Таким образом, вы исключаете любые подобные проблемы в будущем.

...