如何在react中将最新状态从子组件传递给父组件

IT技术 reactjs
2021-05-23 12:51:39

我正在处理一个 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

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

3个回答

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

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

在父组件中定义一个函数

  1. 收到一个论点,即根据您的问题,在此处设置儿童状态
  2. 将此函数作为props传递给子组件
  3. 根据上下文的需要,在设置其状态之前或之后从子组件调用此函数。

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

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

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>