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

如何在每个子挂载上更新父母的状态,而不是在所有子挂载之后?

如何在每个子挂载上更新父母的状态,而不是在所有子挂载之后?

浮云间 2022-10-27 15:12:14
我正在尝试从子元素中更新父元素的状态。我希望更新在每个子元素安装后立即发生,因此我使用useEffect钩子并从那里调用更新函数setData(从父级传递下来)。然而,似乎每个随后被安装的子元素都没有注意到先前安装的子元素对数据所做的更改。也就是说,它对一个空data数组进行操作,而对于第二个、第三个和第四个元素,该数组不应再为空。我相信这是因为setData仅在所有元素安装后才计划执行。这个对吗?如果是这样,我该如何解决这个问题? function Parent() {                        const [data, setData] = React.useState([])                                      function changeData(index, value) {                logData()                let new_data = Array.from(data)                new_data[index] = value                setData(new_data)            }                        function logData() {                console.log(data)            }                        let children = Array(4).fill(null).map((item, index) => {                return <Child id={index} changeData={changeData} />            })                        return (                <div>                    {children}                    <button onClick={logData}>Log data</button>                </div>            )        }  function Child(props) {      const ref = React.useRef(null)      React.useEffect(() => {          props.changeData(ref.current.id, ref.current.id)      }, [])      function onClickHandler(e) {          let element_id = e.target.id          props.changeData(element_id, element_id)      }      return (          <button ref={ref} id={props.id} onClick={onClickHandler}>Child</button>      )  }  ReactDOM.render(<Parent />, document.getElementById('root'))<!DOCTYPE html>    <html>        <body>            <head>                <script src="https://unpkg.com/react@^16/umd/react.production.min.js"></script>                <script src="https://unpkg.com/react-dom@16.13.0/umd/react-dom.production.min.js"></script>                <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>            </head>            <div id="root"></div>        </body>    </html>
查看完整描述

1 回答

?
MM们

TA贡献1886条经验 获得超2个赞

根据当前状态更新状态时,您应该始终使用setState. 有关详细信息,请参阅为什么 setState 给了我错误的值

如果您不使用回调版本,setState对依赖于当前状态的连续调用将相互覆盖,如果它们被 react 批处理,可能会导致不正确的状态。

function changeData(index, value) {

    logData()

    setData(current => {

        // current is the current state including all previous calls to setState in this batch

        const new_data = Array.from(current);

        new_data[index] = value;

        return new_data;

    });

}

更新示例:


function Parent() {

            

            const [data, setData] = React.useState([])

                          

            function changeData(index, value) {

                logData()

                setData(current => {

                  const new_data = Array.from(current);

                  new_data[index] = value;

                  return new_data;

                });

            }

            

            function logData() {

                console.log(data)

            }

            

            let children = Array(4).fill(null).map((item, index) => {

                return <Child id={index} changeData={changeData} />

            })

            

            return (

                <div>

                    {children}

                    <button onClick={logData}>Log data</button>

                </div>

            )

        }


  function Child(props) {


      const ref = React.useRef(null)


      React.useEffect(() => {

          props.changeData(ref.current.id, ref.current.id)

      }, [])


      function onClickHandler(e) {

          let element_id = e.target.id

          props.changeData(element_id, element_id)

      }


      return (

          <button ref={ref} id={props.id} onClick={onClickHandler}>Child</button>

      )

  }


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

<!DOCTYPE html>

    <html>

        <body>

            <head>

                <script src="https://unpkg.com/react@^16/umd/react.production.min.js"></script>

                <script src="https://unpkg.com/react-dom@16.13.0/umd/react-dom.production.min.js"></script>

                <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>

            </head>

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

        </body>

    </html>

编辑useEffect:我创建了一个带有可能解决方案的沙箱,您的孩子不需要:



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

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信