我有一个简单的React组件,名为Child,当单击时,它会增加其计数.此外,还保存了一个外部状态,该状态在Child组件递增时更新.

const Child = ({ onChange }) => {
  const [count, setCount] = useState(0);
  return (
    <div>
      <h1
        onClick={() => {
          setCount(prev => prev + 1);
          onChange(1);
        }}
      >
        Child count = {count}
      </h1>
    </div>
  );
};
const App = () => {
  const [count, setCount] = useState(0);

  return (
    <div className="App">
      <h1> Parent Count = {count} </h1>

      <Child onChange={(i) => setCount(count + i)} />
    </div>
  );
}

上述代码按预期工作.然而,当我使用上下文API来管理外部状态时,Child组件的内部计数保持在0.

const App = () => {
  const [count, setCount] = useState(0);

  const AppContext = React.createContext();

  return (
    <div className="App">
      <AppContext.Provider value={{ state: count, setState: setCount }}>
        <>
          <AppContext.Consumer>
            {({ state }) => <h1> Parent Count = {state} </h1>}
          </AppContext.Consumer>

          <AppContext.Consumer>
            {({ state, setState }) => (
              <Child onChange={(i) => setState(state + i)} />
            )}
          </AppContext.Consumer>
        </>
      </AppContext.Provider>
    </div>
  );
};

样品CodeSandbox.

为什么AppContext.Provider内元件的内部状态总是重置为其初始状态?

推荐答案

首先,上下文的创建应该在组件之外,这意味着这一行:

const AppContext = React.createContext()

应该在App之外.其次,上下文设置可以更简单,如下所示(我在自己的文件中分离了每个组件,因此它类似于常见用例),并使用Forking 代码Sandbox here.

应用程序:

import { useState, createContext } from "react";
import Child from "./Child";
export const AppContext = createContext();

const App = () => {
  const [count, setCount] = useState(0);

  return (
    <div className="App">
      <h1> Parent Count = {count} </h1>
      <AppContext.Provider value={{ state: count, setState: setCount }}>
        <Child />
      </AppContext.Provider>
    </div>
  );
};

export default App;

children :

import { useContext, useState } from "react";
import { AppContext } from "./App";

const Child = () => {
  const { state, setState } = useContext(AppContext);
  const [count, setCount] = useState(0);
  return (
    <div>
      <h1
        onClick={() => {
          setCount((prev) => prev + 1);
          setState(state + 1);
        }}
      >
        Child count = {count}
      </h1>
    </div>
  );
};

export default Child;

Javascript相关问答推荐

Codemirsor 6语言包的使用部分是什么?

我的JS代码将按照哪个序列被解释

Python类实现的JavaScript吊坠是什么样子的?

基于变量切换隐藏文本

PrivateRoute不是路由组件错误

如何将Map字符串,布尔值转换为{key:string;value:bo布尔值;}[]?<>

无法读取未定义错误的属性路径名''

XSLT处理器未运行

如何使用子字符串在数组中搜索重复项

不能将空字符串传递给cy.containes()

用于在路径之间移动图像的查询

第二次更新文本输入字段后,Reaction崩溃

Vaadin定制组件-保持对javascrip变量的访问

为什么可选参数的顺序会导致问题?

使用自动识别发出信号(&Q)

在JS/TS中将复杂图形转换为数组或其他数据 struct

我正在试着做一个TicTacToe Ai来和我玩.但是,我试着在第一个方块被点击时出现一个X,然后在第二个方块之后出现一个O

如何根据查询结果重新排列日期

在JavaScript中将Base64转换为JSON

通过解构/功能组件接收props-prop验证中缺少错误"