为了账号安全,请及时绑定邮箱和手机立即绑定

反应子状态没有得到更新

反应子状态没有得到更新

陪伴而非守候 2022-12-02 17:05:59
我有一个使用挂钩初始化状态的父组件。我将钩子的状态和 setState 传递给子对象,但是每当我更新多个子对象的状态时,它们都会更新不是最新状态的状态。重现问题:当您建立链接并写入您的信息并单击提交时,它会成功附加到父状态。如果在那之后添加另一个,它也会成功附加到父状态。但是当你返回并在第一个链接上按提交时,它会出于某种原因破坏第二个链接。请在我的 codesandbox 上试用。基本上我想要的是一个创建新表单的按钮。在每种形式中,您都可以选择一种社交媒体类型,如 fb、instagram、tiktok,还可以输入一个文本字段。这些数据存储在状态中,最后当您单击应用更改时,我希望它存储在我的数据库中,即 firestore。你能帮我解决这个问题吗?这是一个代码沙箱。https://codesandbox.io/s/blissful-fog-oz10p这是我的代码:管理员.jsimport React, { useState } from 'react';import Button from '@material-ui/core/Button';import AddNewLink from './AddNewLink';const Admin = () => {  const [links, setLinks] = useState({});  const [newLink, setNewLink] = useState([]);  const updateLinks = (socialMedia, url) => {     setLinks({      ...links,      [socialMedia]: url    })  }  const linkData = {    links,    updateLinks,  }    const applyChanges = () => {    console.log(links);    // firebase.addLinksToUser(links);  }  return (    <>      {newLink ? newLink.map(child => child) : null}      <div className="container-sm">        <Button        type="submit"        fullWidth        variant="contained"        color="primary"        onClick={() => {          setNewLink([ ...newLink, <AddNewLink key={Math.random()} linkData={linkData} /> ])}        }      >        Add new social media      </Button>      <Button        type="submit"        fullWidth        variant="contained"        color="primary"        style={{marginTop: '50px'}}        onClick={() => applyChanges()}      >        Apply Changes      </Button>      <h3>{JSON.stringify(links, null, 4)}</h3>      </div>    </>  );}export default Admin;
查看完整描述

1 回答

?
猛跑小猪

TA贡献1858条经验 获得超8个赞

我所看到的是 AddNewLink 中的链接将是一个陈旧的关闭,但在你的问题中你永远不会使用它。这是您的代码“有效”,因为您没有描述它应该做什么它总是“有效”


const { useState } = React;


const AddNewLink = (props) => {

  const [socialMedia, setSocialMedia] = useState('');

  const [url, setUrl] = useState('');

  const { updateLinks, links } = props.linkData;

  console.log('links is a stale closure:', links);


  const handleSubmit = () => {

    updateLinks(socialMedia, url);

  };


  return (

    <div>

      <select

        value={socialMedia}

        onChange={(e) => {

          setSocialMedia(e.target.value);

        }}

      >

        <option value="">select item</option>

        <option value={'facebook'}>Facebook</option>

        <option value={'instagram'}>Instagram</option>

        <option value={'tiktok'}>TikTok</option>

      </select>

      <input

        type="text"

        id="standard-basic"

        label="Enter link"

        style={{ width: '95%' }}

        onChange={(e) => {

          setUrl(e.target.value);

        }}

      />

      <button

        type="submit"

        variant="contained"

        color="primary"

        style={{ marginBottom: '30px' }}

        onClick={() => handleSubmit()}

      >

        Submit

      </button>

    </div>

  );

};


const Admin = () => {

  const [links, setLinks] = useState({});

  const [newLink, setNewLink] = useState([]);


  const updateLinks = (socialMedia, url) =>

    setLinks({

      ...links,

      [socialMedia]: url,

    });


  const linkData = {

    links,

    updateLinks,

  };


  const applyChanges = () => {

    console.log(links);

    // firebase.addLinksToUser(links);

  };


  return (

    <React.Fragment>

      {newLink ? newLink.map((child) => child) : null}

      <div className="container-sm">

        <button

          type="submit"

          variant="contained"

          color="primary"

          onClick={() => {

            setNewLink([

              ...newLink,

              <AddNewLink

                key={Math.random()}

                linkData={linkData}

              />,

            ]);

          }}

        >

          Add new social media

        </button>

        <button

          type="submit"

          variant="contained"

          color="primary"

          style={{ marginTop: '50px' }}

          onClick={() => applyChanges()}

        >

          Apply Changes

        </button>

        <h3>{JSON.stringify(links, null, 4)}</h3>

      </div>

    </React.Fragment>

  );

};


ReactDOM.render(<Admin />, document.getElementById('root'));

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>

<div id="root"></div>

将 jsx 置于本地状态并不是一个好主意,而是将数据保存在状态中并将其传递给每次渲染的组件。



查看完整回答
反对 回复 2022-12-02
  • 1 回答
  • 0 关注
  • 203 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号