关于使用 useContext 和 useReducer 钩子的问题
Question around using useContext and useReducer hooks
我正在尝试练习使用钩子,但我无法绕过它。
我有一个组件 MessageBoard
组件,它从状态中读取数据,它只显示一个简单的消息列表。
我通过 createContext
传递 dispatch
和 state
以便子组件可以使用它,这又在子组件中使用 useContext
读取值。
刷新页面时,我希望看到初始的 UI,但它无法呈现上下文中的值未定义。我在初始化的时候已经给reducer提供了初始状态。
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;
useContext
接受上下文对象(从 React.createContext
返回的值)和 returns 该上下文的当前上下文值。
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);
...
}
工作失败的例子:
我正在尝试练习使用钩子,但我无法绕过它。
我有一个组件 MessageBoard
组件,它从状态中读取数据,它只显示一个简单的消息列表。
我通过 createContext
传递 dispatch
和 state
以便子组件可以使用它,这又在子组件中使用 useContext
读取值。
刷新页面时,我希望看到初始的 UI,但它无法呈现上下文中的值未定义。我在初始化的时候已经给reducer提供了初始状态。
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;
useContext
接受上下文对象(从 React.createContext
返回的值)和 returns 该上下文的当前上下文值。
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);
...
}
工作失败的例子: