Javascript 不能';无法从子状态正确初始化父组件中的状态

Javascript 不能';无法从子状态正确初始化父组件中的状态,javascript,reactjs,Javascript,Reactjs,我有两个React组件,即Form和SimpleCheckbox。 SimpleCheckbox使用了一些重要的UI组件,但我相信它们与我的问题无关 在表单中,使用effect调用api.getCategoryNames(),该函数解析为一个类别数组,例如,[“信息”、“调查”、“交易”、“痛苦”] 我的目标是访问父组件(表单)中复选框的状态(选中或未选中)。我已采用中建议的方法。(参见验证答案) 有趣的是,当我记录检查时,它给出了(api调用解析后): {Pain:false} 我所期望的是

我有两个React组件,即
Form
SimpleCheckbox
SimpleCheckbox
使用了一些重要的UI组件,但我相信它们与我的问题无关

表单中
,使用effect调用
api.getCategoryNames()
,该函数解析为一个类别数组,例如,
[“信息”、“调查”、“交易”、“痛苦”]

我的目标是访问父组件(
表单
)中复选框的状态(选中或未选中)。我已采用中建议的方法。(参见验证答案)

有趣的是,当我记录
检查
时,它给出了(api调用解析后):

{Pain:false}
我所期望的是:

{
资料:假,,
调查:假,,
交易:虚假,
痛苦:错,
}
此外,
在我点击复选框时检查
状态更新是否正确。例如,假设我选中了
信息
调查
框,
检查
变成以下内容:

{
痛苦:错,
信息:没错,
调查:对,,
}
以下是组件:

const Form=()=>{
const[checks,setChecks]=useState({});
const[categories,setCategories]=useState([]);
常量handleCheckChange=(已检查,类别)=>{
setChecks({…checks,[category]:isChecked});
}
useffect(()=>{
应用程序编程接口
.getCategoryNames()
。然后(_类别)=>{
setCategories(_categories);
})
.catch((错误)=>{
console.log(错误);
});
}, []);
返回(
{categories.map(category=>{
}
)
}
const SimpleCheckbox=({onCheck,label,id})=>{
const[check,setCheck]=useState(false);
常量handleChange=(事件)=>{
setCheck(event.target.checked);
};
useffect(()=>{
onCheck(check,id);
},[检查];
返回(
);
}

看起来您在表单级别和复选框组件级别两次控制状态

我消除了其中一个状态并更改了处理程序。此外,我将检查设置为具有initialState,这样您就不会得到
非受控到受控输入警告

import React, { useState, useEffect } from "react";
import { FormControl, FormControlLabel, Checkbox } from "@material-ui/core";
import "./styles.css";

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <Form />
    </div>
  );
}

const Form = () => {
  const [checks, setChecks] = useState({
    Information: false,
    Investigation: false,
    Transaction: false,
    Pain: false
  });
  const [categories, setCategories] = useState([]);
  console.log("checks", checks);
  console.log("categories", categories);
  const handleCheckChange = (isChecked, category) => {
    setChecks({ ...checks, [category]: isChecked });
  };

  useEffect(() => {
    // api
    //   .getCategoryNames()
    //   .then(_categories => {
    //     setCategories(_categories);
    //   })
    //   .catch(error => {
    //     console.log(error);
    //   });
    setCategories(["Information", "Investigation", "Transaction", "Pain"]);
   
  }, []);

  return (
    <>
      {categories.map(category => (
        <SimpleCheckbox
          label={category}
          onCheck={handleCheckChange}
          key={category}
          id={category}
          check={checks[category]}
        />
      ))}
    </>
  );
};

const SimpleCheckbox = ({ onCheck, label, check }) => {
  return (
    <FormControl>
      <FormControlLabel
        control={
          <Checkbox
            checked={check}
            onChange={() => onCheck(!check, label)}
            color="primary"
          />
        }
        label={label}
      />
    </FormControl>
  );
};
我硬编码了categoriesFromApi变量,请确保在api调用语句前面添加
wait

let categoriesFromApi = await axios.get(url)
最后,将初始状态片设置为空对象

const [checks, setChecks] = useState({});

我缺少的是在
setChecks
中使用函数更新。它说:
如果新状态是使用以前的状态计算的,则可以将函数传递给setState。

因此,在改变之后:

const handleCheckChange=(已检查,类别)=>{
setChecks({…checks,[category]:isChecked});
}

const handleCheckChange=(已检查,类别)=>{
setChecks(prevChecks=>{…prevChecks,[类别]:isChecked});
}

它已经开始像我预期的那样工作。

Hello@Hyetigran,我真的无法初始化
检查
状态,因为API的响应可能会改变。@cagruisal现在呢?
const [checks, setChecks] = useState({});