从动态创建的子组件更改状态 - React

Posted

技术标签:

【中文标题】从动态创建的子组件更改状态 - React【英文标题】:Change state from dynamically created child component - React 【发布时间】:2020-04-07 03:33:04 【问题描述】:

在这个应用程序中,您可以通过点击特定比赛的GOAL 按钮来更改足球比赛的比分。问题是我的匹配保存在状态中,我使用map 方法渲染它们,我不能为每个匹配动态使用 setState。

App.js

import React from 'react';

import Match from './components/Match';

import './App.css';

export default class App extends React.Component 
  constructor(props) 
    super(props);

    this.state = 
      games: [
        
          home: 
            team: "Bruges",
            score: 0
          ,
          guests: 
            team: "Real Madrid",
            score: 0
          
        ,
        
          home: 
            team: "Atletico Madrid",
            score: 0
          ,
          guests: 
            team: "Lokomotiv",
            score: 0
          
        
      ]
    ;

    this.goal = this.goal.bind(this);
  ;

  goal(parent) 
    let rand = Math.round(Math.random());

    if(rand) 
      this.setState((prevstate) => (parent:  prevstate.parent.home.score + 1))
     else 
      this.setState((prevstate) => (parent: prevstate.parent.guests.score + 1))
    
  

  render() 
    return (
      <div className="App">
        this.state.games.map((item, index) => 
          return (<Match 
            key=index

            home=item.home.team
            homeScore=item.home.score

            guests=item.guests.team       
            guestsScore=item.guests.score

            goal=() => this.goal(item)
          />);
        )
      </div>
    );
  


Match.js

import React from 'react';

import '../App.css'

const Match = props => 
    return(
    <div className="match-container">
        <span className="name-container">props.home </span>
        <span className="score-container">props.homeScore</span>

        <button onClick=props.goal>GOAL</button>

        <span className="score-container">props.guestsScore </span>
        <span className="name-container">props.guests </span>
    </div>
    );


export default Match;

CodeSandBox

我认为我的问题出在goal 方法中,因为我认为我不能传递参数并在setState 中使用它。

我没有找到与这个特定问题相关的答案。

【问题讨论】:

你想更新点击按钮的值吗? @VahidAkhtar 我想更新 homeScore 或 guestScore 游戏必须是数组吗?如果它是一个每个游戏都有一个唯一键的对象,那就简单多了。您可以更改实现还是必须使用数组? @JoshPittman 是的,在这种情况下我需要使用数组:/ 【参考方案1】:

问题是你试图更新一个数组,就好像它是一个对象一样。事实是您已将游戏设置为状态数组。更新方法如下:

goal(parent) 
    let rand = Math.round(Math.random());
    const  games  = this.state;
    const index = games.findIndex(element => element === parent);
    const newGames = [...games];
    if (rand) 
      newGames[index].home.score = newGames[index].home.score + 1;
     else 
      newGames[index].guests.score = newGames[index].guests.score + 1;
    
    this.setState( games: newGames );
  

这是一个工作演示https://codesandbox.io/s/practical-margulis-n0ch1

【讨论】:

因此,如果我理解正确,您会分散状态并仅采用 games 数组。然后你从被点击的按钮的索引中取出索引,然后再次取出games数组并将其分配给newGames,用条件更改它并设置为状态? 是的,你永远不应该改变状态。如果要进行更改,请创建要更改的位的副本,更新它,然后保存更新的版本。这与我的回复无关,这只是反应最佳实践daveceddia.com/why-not-modify-react-state-directly reactjs.org/docs/… 非常感谢您的解决方案和进一步的解释。这是一个完全令人满意的答案!!!

以上是关于从动态创建的子组件更改状态 - React的主要内容,如果未能解决你的问题,请参考以下文章

如何在 React 中动态创建状态?

从动态创建的子组件向父组件发出事件

使用 React 创建动态 UI

React Apollo:从组件状态动态更新 GraphQL 查询

根据外部 Internet 连接动态更改状态 - React(离线/在线)

如何使用状态动态更改 React Native 转换?