Реакция: почему не обновляется значение моего контекста?

#javascript #reactjs #jsx #context-api

#javascript #reactjs #jsx #реагировать-контекст

Вопрос:

Я играю с контекстным API React. Я создал простой компонент:

 import React, { createContext, useContext } from 'react';

const MyContext = createContext(1);

const MyComponent = () => (
    <>
        <p>{useContext(MyContext)}</p>
        <MyContext.Provider value={2}>
            <p>{useContext(MyContext)}</p>
        </MyContext.Provider>
    </>
);

export default MyComponent;
 

Я получаю два <p>1</p> . Почему второй контекст не обновляется с 2 помощью ? Я неправильно использую useContext() ?

Ответ №1:

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

Я отправил ошибку об этом; см. https://github.com/facebook/react/issues/18629

Просто разделите код, используя контекст, на другой компонент.

 const Inner = () => (
    <p>{useContext(MyContext)}</p>
);

const MyComponent = () => (
    <>
        <p>{useContext(MyContext)}</p>
        <MyContext.Provider value={2}>
            <Inner />
        </MyContext.Provider>
    </>
);
 

Это должно это исправить.

Комментарии:

1. Спасибо! Я использовал Context в прошлом, и у меня не было никаких проблем. Сейчас я экспериментирую, чтобы лучше понять это, и я был удивлен, что мой пример не сработал так, как ожидалось. Я согласен, что это ошибка!

2. Я чувствовал то же самое. Потратил кучу времени, пытаясь выяснить, почему. Но если наш Господь и Спаситель Дэн Абрамов не считает, что это ошибка, то это не так. (Однако не стесняйтесь оказывать давление на Дэна, добавляя 1 к проблеме или связывая этот вопрос SO там)

3. Ну, в React есть более запутанные вещи, так что, я думаю, это сделано специально: D

Ответ №2:

Вам нужно будет отобразить другой компонент внутри поставщика контекста, чтобы получить значение 2. Как useContext указано в документации:

Принимает объект контекста (значение, возвращаемое из React.createContext ) и возвращает текущее значение контекста для этого контекста. Текущее значение контекста определяется значением prop ближайшего <MyContext .Поставщик> над вызывающим компонентом в дереве.

Курсив добавлен. Важным моментом является то, что не имеет значения, где вы вызываете useContext внутри компонента — важно то, где находится тот компонент, в котором он вызывается, в дереве.

 import React, { createContext, useContext } from "react";

const MyContext = createContext(1);

const ChildComponent = () => (
  <p>{useContext(MyContext)}</p>
)

const MyComponent = () => (
  <>
      <p>{useContext(MyContext)}</p>
      <MyContext.Provider value={2}>
        <ChildComponent/>
      </MyContext.Provider>
  </>
);

export default MyComponent;
 

Комментарии:

1. Удивлен, что я получил здесь accept, понравилась ваша цитата из документации.