有关使用useContext和useReducer挂钩的问题

时间:2019-07-18 23:09:38

标签: javascript reactjs react-hooks

我正在尝试练习使用挂钩,但我无法将其缠绕在头上。 我有一个单独的组件MessageBoard组件,它从状态中读取数据,该状态仅显示简单的消息列表。

我正在通过dispatch传递statecreateContext,以便子组件可以使用它,而子组件又在子组件中使用useContext来读取值。

刷新页面时,我希望看到初始的UI,但无法呈现上下文中的值未定义。初始化时,我已经向减速器提供了初始状态。

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;

MessagesContext.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中,它将按预期工作。想知道我在这里误解了什么以及可能会发生什么?

MessagesContext.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

1 个答案:

答案 0 :(得分:2)

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