【问题标题】:How to pass latest state to a Parent component from Child Component in react如何在反应中将最新状态从子组件传递给父组件
【发布时间】:2020-06-30 15:36:57
【问题描述】:

我正在开发一个 React 项目,在我的项目中,我有两个组件,即 App 和 Child。 应用是父组件,子是子组件。

现在,当我单击子组件上的按钮时,我更改了子组件中的状态。

现在我的目标是如何为父组件按钮传递子组件的最新状态。

我不知道如何做到这一点,请帮助我

这是 App.js

import React from 'react';
import './App.css';
import Child from './Child/Child';

function App() {
  return(
    <div className='container'>
      <div className='row'>
        <button className='btn btn-primary'>Click here</button>
        <Child></Child>
      </div>
    </div>
  )
}

export default App

这是 Child.js

import React, { useState } from 'react';
import './Child.css';

function Child() {
    const [color, setColor] = useState('yellow');
    const [textColor, setTextColor] = useState('white');
    return (
        <div className='container'>
            <div className='row'>
                <button style={{ background: color, color: textColor }} 
                onClick={()=>{setColor("black");setTextColor('red')}}className='btn btn-danger mt-5'>Click here</button>
            </div>
        </div>
    )
}

export default Child

如果您觉得我的疑问不清楚,请发表评论。 谢谢。

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    您不能将数据从子级传递给父级,只需将数据存储在父级中并将其传递给如下所示的子级

    function App() {
    
    const [color, setColor] = useState('yellow');
      const [textColor, setTextColor] = useState('white');
      return (
        <div className='container'>
          <div className='row'>
            <button className='btn btn-primary'>Click here</button>
            <Child
               color={color} 
               setColor={color => setColor(color)}
               textColor={textColor}
               setTextColor={textColor => setTextColor(textColor)}
            />
          </div>
        </div>
      )
    }
    
    export default App
    
    import React from 'react';
    import './Child.css';
    
    function Child(props) {
        const {color, setColor, textColor, setTextColor} = props;
        return (
            <div className='container'>
                <div className='row'>
                    <button style={{ background: color, color: textColor }} 
                    onClick={()=>{setColor('red');setTextColor('black')}}className='btn btn-danger mt-5'>Click here</button>
                </div>
            </div>
        )
    }
    
    export default Child
    

    【讨论】:

    • 嗨@iamhuynq,它显示如下错误:预期一个赋值或函数调用,而是看到一个表达式 no-unused-expressions:预期一个赋值或函数调用,而是看到一个表达式 no-unused-表达式
    • 你需要调用setter:onClick={()=&gt;{setColor(withWhat?);setTextColor(withWhat?)}}
    • 嗨@Cruse这个错误可能是因为return的括号,你可以在这里查看stackoverflow.com/questions/53013437/…@HMR谢谢你,我已经更新了代码
    【解决方案2】:

    在父组件中定义一个函数

    1. 根据您的问题在此处接收参数,即子状态
    2. 将此函数作为道具传递给子组件
    3. 根据上下文的需要,在设置其状态之前或之后从子组件调用此函数。

    我在构建 React 应用程序时多次使用过这种方法。 如果对您有帮助,请接受此作为答案。

    【讨论】:

      【解决方案3】:

      如果您的子组件具有复杂的逻辑,您不希望父组件被打扰,您可以将回调从父组件传递给子组件:

      function Child({ onColorChanged }) {
        //The disadvantage of this is that you can't pass in
        //  default values for color and textColor from Parent
        const [color, setColor] = React.useState('yellow');
        const [textColor, setTextColor] = React.useState('white');
        //When color or textColor changes call the onColorChanged
        //  callback/event handler
        React.useEffect(
          () => onColorChanged({ color, textColor }),
          //the onColorChanged callback/event handler is
          //  a dependency of this effect, that is why
          //  Parent uses useCallback so it won't change
          //  when parent re renders
          [color, textColor, onColorChanged]
        );
        return (
          <div className="container">
            <div className="row">
              <button
                style={{ background: color, color: textColor }}
                onClick={() => {
                  //some complicated logic you don't want in the
                  //  parent
                  setColor('black');
                  setTextColor('red');
                }}
                className="btn btn-danger mt-5"
              >
                Click here
              </button>
            </div>
          </div>
        );
      }
      
      function Parent() {
        const [state, setState] = React.useState();
        const onColorChanged = React.useCallback(
          color => setState(old => ({ ...old, color })),
          []
        );
        console.log('state is now:', state);
        return (
          <div className="container">
            <div className="row">
              <button className="btn btn-primary">
                Click here
              </button>
              <Child onColorChanged={onColorChanged}></Child>
            </div>
          </div>
        );
      }
      
      ReactDOM.render(<Parent />, 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>

      如果 Child 没有您不想在 Parent 中使用的复杂逻辑,您可以让 Parent 管理状态并在发生变化时传递回调。

      const colors = ['yellow', 'gold', 'black', 'white'];
      function Child({ setColor, color: { color, textColor } }) {
        return (
          <div className="container">
            <h1 style={{ background: color, color: textColor }}>
              Hello world
            </h1>
            <label>
              color
              <select
                value={color}
                onChange={e => setColor('color', e.target.value)}
              >
                {colors.map(c => (
                  <option value={c} key={c}>
                    {c}
                  </option>
                ))}
              </select>
            </label>
            <label>
              text color
              <select
                value={textColor}
                onChange={e =>
                  setColor('textColor', e.target.value)
                }
              >
                {colors.map(c => (
                  <option value={c} key={c}>
                    {c}
                  </option>
                ))}
              </select>
            </label>
          </div>
        );
      }
      
      function App() {
        const [state, setState] = React.useState({
          color: 'yellow',
          textColor: 'white',
        });
        const setColor = React.useCallback(
          (key, value) =>
            setState(old => ({ ...old, [key]: value })),
          []
        );
        return (
          <div className="container">
            <div className="row">
              <Child setColor={setColor} color={state}></Child>
            </div>
          </div>
        );
      }
      
      ReactDOM.render(<App />, 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>

      【讨论】:

        猜你喜欢
        • 2021-06-30
        • 2021-10-23
        • 2021-01-23
        • 2019-02-17
        • 2020-07-04
        • 2022-07-15
        • 1970-01-01
        • 2019-08-15
        相关资源
        最近更新 更多