Вопрос об использовании хуков useContext и useReducer

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

Я передаю dispatch и state через createContext, чтобы дочерние компоненты могли их использовать, что, в свою очередь, использует useContext в дочерних компонентах для чтения значения.

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

App.js

import React from "react";

import MessageBoard from "./MessageBoard";

import MessagesContext from "../context/MessagesContext";

function App() {
  return (
    <div>
      <MessagesContext>
        <h2>Reaction</h2>
        <hr />
        <MessageBoard />
      </MessagesContext>
    </div>
  );
}

export default App;

MessageBoard.js

import React, { useContext } from "react";

import MessagesContext from "../context/MessagesContext";

function MessageBoard(props) {
  const { state } = useContext(MessagesContext);

  return (
    <div>
      {state.messages.map(message => {
        return (
          <div key = {message.id}>
            <h4>{new Date(message.timestamp).toLocaleDateString()}</h4>
            <p>{message.text}</p>
            <hr />
          </div>
        );
      })}
    </div>
  );
}

export default MessageBoard;

СообщенияContext.js

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

import reducer, { initialState } from "../state/reducer";

export default function MessagesContext(props) {
  const Context = createContext(null);
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <Context.Provider
      value = {{
        dispatch,
        state
      }}
    >
      {props.children}
    </Context.Provider>
  );
}

Сломанный пример — https://codesandbox.io/s/black-dust-13kj2

Вместо этого, если я немного изменю файл MessagesContext и вместо этого Provider будет напрямую внедрен в App, он будет работать, как и ожидалось. Хотите знать, что я неправильно понял здесь и что может происходить?

СообщенияContext.js

import { createContext } from "react";

export default createContext(null);

App.js

import React, { useReducer } from "react";

import reducer, { initialState } from "../state/reducer";

import PublishMessage from "./PublishMessage";
import MessageBoard from "./MessageBoard";

import MessagesContext from "../context/MessagesContext";

function App() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <MessagesContext.Provider
        value = {{
          dispatch,
          state
        }}
      >
        <h2>Reaction</h2>
        <hr />
        <PublishMessage />
        <hr />
        <MessageBoard />
      </MessagesContext.Provider>
    </div>
  );
}

export default App;

Рабочий пример — https://codesandbox.io/s/mystifying-meitner-vzhok

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
408
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

useContext принимает объект контекста (значение, возвращаемое из React.createContext) и возвращает текущее значение контекста для этого контекста.

const MyContext = createContext(null);
const value = useContext(MyContext);
// MessagesContext Not a contex object.
const { state } = useContext(MessagesContext);

В первом примере:

// export the context.
export const Context = createContext(null);

export default function MessagesContext(props) {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <Context.Provider
      value = {{
        dispatch,
        state
      }}
    >
      {props.children}
    </Context.Provider>
  );
}

а затем используйте его:

import { Context } from '../context/MessagesContext';

function MessageBoard() {
  const { state } = useContext(Context);
...
}

Рабочий сломанный пример:

Edit Q-57103683-useContext

О, просмотрел код (не запускал песочницы) и полностью пропустил useContext(MessageContext) (MessageContext на самом деле не является контекстом!). Хорошее место.

James 19.07.2019 02:48

Спасибо за ответ. Похоже, это то, что я неправильно понял. В этом сценарии я использовал компонент, а не объект контекста. Кроме того, поскольку createContext был определен внутри компонента, он также создавал новый объект контекста при рендеринге.

Sushanth -- 19.07.2019 06:19

Другие вопросы по теме