如何从 React 中的父类更新我的子组件状态?

Posted

技术标签:

【中文标题】如何从 React 中的父类更新我的子组件状态?【英文标题】:How can I update my child component state from the parent class in React? 【发布时间】:2020-11-15 23:51:47 【问题描述】:

我目前有一个父类 (App) 和一个子组件 (FoodItem)。 App 组件映射一个 FoodItem 组件列表。

每个单独的 FoodItem 组件都有一个称为 clickCount 的状态,每次用户单击它时都会递增。但是,我需要我的 App 组件中的重置按钮将地图中所有 FoodItem 组件的 FoodItem 状态重置为 0 onClick。

对此的任何帮助将不胜感激。

更新 - 我已经设法获得重置按钮来更新 FoodItem 子组件,但它只更新映射列表中的最后一项,而我要求它更新列表中的所有项目。

    class App extends React.Component 

  constructor(props) 
    super(props);
    this.myRef = React.createRef();
    this.state = 
      foods: FoodCards,
      calorieCount: 0,
      vitaminACount: 0,
      vitaminDCount: 0,
    ;
    this.increment = this.increment.bind(this);
  

  increment = (calories = 0, vitaminA = 0, vitaminD = 0) => 
    this.setState(
      calorieCount: Math.round(this.state.calorieCount + calories),
      vitaminACount: Math.round((this.state.vitaminACount + vitaminA) * 100) / 100,
      vitaminDCount: Math.round((this.state.vitaminDCount + vitaminD) * 100) / 100
    );
  ;

  resetCounters = () => 
    this.myRef.current.resetClickCount();
    this.setState(
      calorieCount: 0,
      vitaminACount: 0,
      vitaminDCount: 0,
    );
  ;

  render() 

    return (
      <div className="App">
  
        <main className="products-grid flex flex-wrap">
  
        this.state.foods.map((item, i) => 
          return <FoodItem key=item.id ref=this.myRef name=item.name img=item.img calories=item.calories vitamin_a=item.vitamin_a vitamin_d=item.vitamin_d updateTotals = this.increment />
        )
  
        </main>

        <footer>
          <div className="reset" onClick=() => this.resetCounters()>Reset</div>
        </footer>
  
      </div>
    );
  


export default App;

class FoodItem extends React.Component 

  constructor(props) 
    super(props);
    this.state = 
      clickCount: 0
    ;
  

  handleUpdateTotals = (calories, vitamin_a, vitamin_d) => 
    this.props.updateTotals(calories, vitamin_a, vitamin_d);
    this.clickIncrement();
  

  clickIncrement = () => 
    this.setState(
      clickCount: this.state.clickCount + 1
    );
  

  resetClickCount = () => 
    this.setState(
      clickCount: 0
    );
  

  render() 
    return (
      <div className="product" onClick=() => this.handleUpdateTotals(this.props.calories, this.props.vitamin_a, this.props.vitamin_d)>
        <p>this.props.name</p>
        this.state.clickCount > 0 ? <p>Selected: this.state.clickCount</p> : <p>Not Selected</p>
        <img src=this.props.img  />
      </div>
    );
  

【问题讨论】:

在 FoodItem 中引入一个属性,例如“reset”,当单击“Reste”按钮时,将属性值作为“reset”的 true 传递。如果 props.reset===true,在 FoodItem 组件中将 clickCount 设置为 0。 您应该提升状态并将点击计数保留在您的父组件中。 reactjs.org/docs/lifting-state-up.html 【参考方案1】:

您应该根据反应 docs 提升状态。当两个子级影响相同的状态(重置按钮和 clickCount)时,应该将状态提升到包含这两个子级的父级。所以你的计数应该存储在父级中。

但是...要回答您的问题,您可以轻松地执行以下操作以在每次单击按钮时触发渲染(但不推荐):

const [resetCount, setResetCount] = useState(false);

const resetCountClicked = () => setResetCount(!resetCount);

return 
  <>
    <Child resetCount=resetCount></Child>
    <button onClick=() => resetCountClicked()>Reset Count</button>
  </>

在孩子中包括:

useEffect(() => setCount(0), [resetCount]);

这是使用带有函数组件的钩子和 useEffect 来在每次 prop resetCount 更改时运行一个事件。

对于类,您可以使用传递给子级的 ref,如 post 所示。

const  Component  = React;

class Parent extends Component 
  constructor(props) 
    super(props);
    this.child = React.createRef();
  

  onClick = () => 
    this.child.current.resetCount();
  ;

  render() 
    return (
      <div>
        <Child ref=this.child />
        <button onClick=this.onClick>Reset Count</button>
      </div>
    );
  

在孩子身上……

  resetCount() 
    this.setState(
      clickCount: 0
    );
  

【讨论】:

谢谢。我使用了 classes 和 child ref,因为我对 React 还很陌生,提升状态是我需要弄清楚的事情。但是,重置按钮现在只更新映射对象中最后一个 的状态.. reactjs.org/docs/thinking-in-react.html 你应该阅读这个。您需要为每个孩子提供一个单独的参考... useEffect 方法对您很有效 - 如果您只是学习 React 为什么不使用函数组件? Hooks 更新了,React 正在发展。

以上是关于如何从 React 中的父类更新我的子组件状态?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用从 React 中的子组件获取的数据更新父组件中的状态

如何在 React 中更新 chart.js 的状态

React 子组件在父组件中更新状态后如何将其重置回原始状态

React - 父类组件功能改变子组件的类

问题将Redux与来自React的父道具连接起来

FlatList 不渲染从服务器获取的父组件数据,在 React Native 的子组件中