【Flutter】多组件共用状态,父组件状态传递给子组件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了【Flutter】多组件共用状态,父组件状态传递给子组件相关的知识,希望对你有一定的参考价值。

参考技术A 场景:多个组件共用一个状态,子组件通过方法改变父组件状态
思路:状态和管理方法定义在父组件,通过构造函数传递给子组件

其他子组件按照同样方法接收即可共用该父组件的状态。

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

【中文标题】如何在反应中将最新状态从子组件传递给父组件【英文标题】: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

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

【问题讨论】:

【参考方案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的括号,你可以在这里查看***.com/questions/53013437/…@HMR谢谢你,我已经更新了代码【参考方案2】:

在父组件中定义一个函数

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

我在构建 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>

【讨论】:

以上是关于【Flutter】多组件共用状态,父组件状态传递给子组件的主要内容,如果未能解决你的问题,请参考以下文章

将子组件的状态传递给父组件?

如何在反应中将子组件的状态数组传递给父组件?

通过反应上下文 api 将子状态传递给父组件

Flutter 功能型组件:跨组件状态共享(Provider)

React:将状态传递给子组件

在设置子组件的数组状态并将其通过反应测验传递回父组件时出现问题