简体   繁体   English

使用子组件更新父 State

[英]Updating Parent State with Child component

I am working on my first React project as a simple spend tracker on CC's.我正在开发我的第一个 React 项目,作为 CC 上的简单支出跟踪器。 My description might be loose as I am still learning but hopefully you'll see through my code what I am trying to do.我的描述可能很松散,因为我仍在学习,但希望你能通过我的代码看到我正在尝试做的事情。 I am stuck on mapping my state and giving an index but including the input date and button through each array value of the state.我坚持映射我的 state 并给出索引,但包括通过 state 的每个数组值的输入日期和按钮。

class App extends Component {
  state = {
    cards: [
      { id: 'asfa1', name: 'Capital One', balance: 28 },
      { id: 'vasdf1', name: 'Barclays', balance: 29 },
      { id: 'asdf11', name: 'Discover', balance: 26 }
    ],
    totalDue: null
    
  }
theTotal = () => {
    let total = 0;
    let cardOne = this.state.cards[0].balance
    let cardTwo = this.state.cards[1].balance
    let cardThree = this.state.cards[2].balance
   total = cardOne + cardTwo + cardThree
   console.log('made it')
    this.setState( { totalDue : total } )
}
updateBalance = (cardIndex) => {
  let cards = [...this.state.cards]
  console.log('The card index is = ' + cardIndex)
  let oldBalance = cards[cardIndex].balance
  console.log(oldBalance)
  const addedBalance = document.getElementById('balanceInput').value;
  
  const newBalance = oldBalance + parseInt(addedBalance)
  cards[cardIndex].balance = newBalance
  this.setState( {cards : cards})


 }
  
  render () {

    let card = (
      <div> 
        {this.state.cards.map( ( cards , index) => {
          return ( 
          <Cards 
          name={cards.name}
          balance={cards.balance}
          update={() => this.updateBalance(index)} 
          />
          )
        })}
      </div>
    )

This is what the parent class will look like.这就是父 class 的样子。 I think it is also worth mentioning that I was going to attach this to a Firebase table and have it submit updates.我认为还值得一提的是,我将把它附加到 Firebase 表并让它提交更新。 My original plan was to only update the database once the user hits and update button and the state changes will be posted.我最初的计划是仅在用户点击并更新按钮后更新数据库,并且 state 更改将被发布。 But I have also considered having the POST handler be built into each unique Update for the cards.但我也考虑过将 POST 处理程序内置到卡片的每个唯一更新中。 Please see the code below for the child component.请参阅下面的子组件代码。

import React from 'react'
import classes from './Cards.css'
import Input from '../Components/Input'

const cards = (props) => {


return (

    <div className={classes.Cards}>
        <p>{props.name}</p>
        <p>{props.balance}</p>
        {props.children}
        <Input type="text" name="amount" />
        <p></p><button onClick={props.update}>Update Balance</button>
    </div>


)}

export default cards;

My issue is that the first card works and updates.我的问题是第一张卡可以工作并更新。 But when you click the to put in values for the second card, it uses the first value you put on the first one.但是,当您单击 为第二张卡输入值时,它会使用您在第一张卡上输入的第一个值。 If you start on the second card it throws errors and crashes.如果您从第二张卡开始,则会引发错误并崩溃。

Is there a better way to handle the inputs from the child?有没有更好的方法来处理孩子的输入?

App.js应用程序.js


import './App.css';
import React, {Component} from 'react'
import Cards from './Cards'

class App extends Component {
  state = {
    cards: [
      { id: 'asfa1', name: 'Capital One', balance: 28 },
      { id: 'vasdf1', name: 'Barclays', balance: 29 },
      { id: 'asdf11', name: 'Discover', balance: 26 }
    ],
    totalDue: null

  }
theTotal = () => {

    let total = 0;
    this.state.cards.forEach(card => {
      total += card.balance; // looping through each card and adding balance to total
    });

    console.log('made it')
    this.setState( { totalDue : total } )
}
updateBalance = (cardIndex, e) => {

  e.preventDefault();
  const {cards} = this.state;
  console.log('The card index is = ' + cardIndex);

  let oldBalance = cards[cardIndex].balance;
  console.log(oldBalance);
  const addedBalance = e.target[0].value; // target 0 is the input element

  const newBalance = oldBalance + parseInt(addedBalance);
  cards[cardIndex].balance = newBalance;
  this.setState( {cards : cards});



 }

  render () {
    return <div>
      {this.state.cards.map( ( cards , index) => {
        return (
        <Cards
        key={index}
        name={cards.name}
        balance={cards.balance}
        index={index}
        update={this.updateBalance}
        />
        )
      })}
    </div>
  }

}

export default App;

Cards.js Cards.js

import React from 'react'

const cards = (props) => {


return (

    <div>
        <p>{props.name}</p>
        <p>{props.balance}</p>
        {props.children}
        <form onSubmit={(e) => props.update(props.index, e)}>
          <input type="text" name="amount" />
          <p></p><button>Update Balance</button>
        </form>
    </div>


)}

export default cards;

Sandbox: https://codesandbox.io/s/determined-violet-wo05g?file=/src/App.js沙盒: https://codesandbox.io/s/determined-violet-wo05g?file=/src/App.js

In react, updating the parent component's state with child component works like this.在反应中,使用子组件更新父组件的 state 就像这样。

  1. Pass the method as a prop to the child component.将该方法作为道具传递给子组件。
  2. In child component, call this method with a value that you want.在子组件中,使用您想要的值调用此方法。
  3. Inside the parent, implement the method with setState .在父级内部,使用setState实现该方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM