#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, понравилась ваша цитата из документации.