猿问

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

我正在尝试从子元素中更新父元素的状态。


我希望更新在每个子元素安装后立即发生,因此我使用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>


浮云间
浏览 81回答 1
1回答

MM们

根据当前状态更新状态时,您应该始终使用setState.&nbsp;有关详细信息,请参阅为什么 setState 给了我错误的值。如果您不使用回调版本,setState对依赖于当前状态的连续调用将相互覆盖,如果它们被 react 批处理,可能会导致不正确的状态。function changeData(index, value) {&nbsp; &nbsp; logData()&nbsp; &nbsp; setData(current => {&nbsp; &nbsp; &nbsp; &nbsp; // current is the current state including all previous calls to setState in this batch&nbsp; &nbsp; &nbsp; &nbsp; const new_data = Array.from(current);&nbsp; &nbsp; &nbsp; &nbsp; new_data[index] = value;&nbsp; &nbsp; &nbsp; &nbsp; return new_data;&nbsp; &nbsp; });}更新示例:function Parent() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const [data, setData] = React.useState([])&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; function changeData(index, value) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logData()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setData(current => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const new_data = Array.from(current);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_data[index] = value;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new_data;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; function logData() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(data)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let children = Array(4).fill(null).map((item, index) => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return <Child id={index} changeData={changeData} />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {children}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <button onClick={logData}>Log data</button>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; function Child(props) {&nbsp; &nbsp; &nbsp; const ref = React.useRef(null)&nbsp; &nbsp; &nbsp; React.useEffect(() => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; props.changeData(ref.current.id, ref.current.id)&nbsp; &nbsp; &nbsp; }, [])&nbsp; &nbsp; &nbsp; function onClickHandler(e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let element_id = e.target.id&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; props.changeData(element_id, element_id)&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <button ref={ref} id={props.id} onClick={onClickHandler}>Child</button>&nbsp; &nbsp; &nbsp; )&nbsp; }&nbsp; ReactDOM.render(<Parent />, document.getElementById('root'))<!DOCTYPE html>&nbsp; &nbsp; <html>&nbsp; &nbsp; &nbsp; &nbsp; <body>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <head>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <script src="https://unpkg.com/react@^16/umd/react.production.min.js"></script>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <script src="https://unpkg.com/react-dom@16.13.0/umd/react-dom.production.min.js"></script>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </head>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <div id="root"></div>&nbsp; &nbsp; &nbsp; &nbsp; </body>&nbsp; &nbsp; </html>编辑useEffect:我创建了一个带有可能解决方案的沙箱,您的孩子不需要:
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答