Javascript 反应如何修复子组件中的过时状态

Javascript 反应如何修复子组件中的过时状态,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,创建多个子组件(每个子组件都可以设置其父组件的状态)会使这些子组件具有不同版本的状态历史(也称为陈旧状态) 要重现错误,请执行以下操作: 通过单击“添加新社交媒体”创建2个子组件 提交两个子组件以设置父状态 再次提交第一个创建的组件,现在第二个组件输入将从结果状态消失 另一个错误: 通过单击“添加新社交媒体”创建2个子组件 提交第二个创建的子组件 提交第一个创建的子组件,现在第二个组件输入从结果状态消失 总之,我希望结果状态包含每个组件的所有数据。我怎样才能解决这个问题 您面临的问题是由Upda

创建多个子组件(每个子组件都可以设置其父组件的状态)会使这些子组件具有不同版本的状态历史(也称为陈旧状态)

要重现错误,请执行以下操作:

通过单击“添加新社交媒体”创建2个子组件 提交两个子组件以设置父状态 再次提交第一个创建的组件,现在第二个组件输入将从结果状态消失 另一个错误:

通过单击“添加新社交媒体”创建2个子组件 提交第二个创建的子组件 提交第一个创建的子组件,现在第二个组件输入从结果状态消失 总之,我希望结果状态包含每个组件的所有数据。我怎样才能解决这个问题


您面临的问题是由UpdateLink函数在链接状态上关闭引起的

当您创建两个AddNewLink组件时,每个组件都被传递给UpdateLink函数。由于最初links是一个空对象,所以传递给AddNewLink的两个实例的updateLinks函数在links变量上有一个闭包,此时links引用一个空对象{}。因此,当您提交表单时,就UpdateLink函数而言,链接是一个空对象。因此,当将链接与AddNewLink组件传递的数据合并时,只有来自提交表单的数据保存在状态中,因为链接是空对象

解决方案:

您可以使用userefhook访问updateLinks函数中链接的最新值

const Admin = () => {
   ...
   
   const linkRef = useRef();

   const updateLinks = (socialMedia, url) => {
      linkRef.current = { ...linkRef.current, [socialMedia]: url };
      setLinks(linkRef.current);
   };
   
   ...
};
此外,我认为您不需要AddNewLink组件的多个实例。您可以使用AddNewLink组件的单个实例在该州添加多个社交媒体链接

演示:


请将现场堆栈代码段用于可运行的示例,而不是外部站点或外部站点之外的示例。堆栈代码段支持React,包括JSX。遗憾的是,你必须使用而不是。
const AddNewLink = props => {
  const [socialMedia, setSocialMedia] = useState("");
  const [url, setUrl] = useState("");
  const { updateLinks } = props.linkData;

  const handleSubmit = () => {
    updateLinks(socialMedia, url);
  };

  return (
    <>
      <FormControl
        style={{ marginTop: "30px", marginLeft: "35px", width: "90%" }}
      >
        <InputLabel>Select Social Media</InputLabel>
        <Select
          value={socialMedia}
          onChange={e => {
            setSocialMedia(e.target.value);
          }}
        >
          <MenuItem value={"facebook"}>Facebook</MenuItem>
          <MenuItem value={"instagram"}>Instagram</MenuItem>
          <MenuItem value={"tiktok"}>TikTok</MenuItem>
        </Select>
      </FormControl>
      <form
        noValidate
        autoComplete="off"
        style={{ marginBottom: "30px", marginLeft: "35px" }}
      >
        <TextField
          id="standard-basic"
          label="Enter link"
          style={{ width: "95%" }}
          onChange={e => {
            setUrl(e.target.value);
          }}
        />
      </form>
      <div className="container-sm">
        <Button
          type="submit"
          fullWidth
          variant="contained"
          color="primary"
          style={{ marginBottom: "30px" }}
          onClick={() => handleSubmit()}
        >
          Submit
        </Button>
      </div>
    </>
  );
};

export default AddNewLink;

const Admin = () => {
   ...
   
   const linkRef = useRef();

   const updateLinks = (socialMedia, url) => {
      linkRef.current = { ...linkRef.current, [socialMedia]: url };
      setLinks(linkRef.current);
   };
   
   ...
};