列表数组更新时,子组件不会刷新

时间:2019-09-06 21:29:58

标签: reactjs

我是React的新手,我遇到了一个问题,我要通过用户输入调用的函数来更新应用程序组件中的数组列表。这工作正常,但是有一个子组件可以获取列表的内容,并将其映射到其显示的按钮。我的问题是,该列表会在应用程序组件中进行更新,而子组件不会更新。

这是我的应用程序组件的代码:

import React from 'react';
import './App.scss';

import DiceSelector from "./components/DiceSelector";
import ListOfDiceTypes from "./shared/list-available-dice";

const DiceToRollList = [];
const RolledTotal = 45;

DiceToRollList.push(ListOfDiceTypes[4]);
DiceToRollList.push(ListOfDiceTypes[4]);
DiceToRollList.push(ListOfDiceTypes[3]);

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

    render() {
      return (
          <div className="App">
              <header className="App-header">
                  <div className="Dice-Box">
                      <h2>Select Dice to Roll</h2>
                      {ListOfDiceTypes.map((dice, index) => (
                          <DiceSelector
                              key={"typeList" + index}
                              dicetype={dice.dicetype}
                              imagename={dice.imageName}
                              maxvalue={dice.maxvalue}
                              onClick={AddDieClick}
                          />
                      ))}
                  </div>
                  <div className="Dice-Box">
                      <h2>Selected Dice</h2>
                       {DiceToRollList.map((dice, index) => (
                           <DiceSelector
                              key={"SelectedList" + index}
                              dicetype={dice.dicetype}
                              imagename={dice.imageName}
                              maxvalue={dice.maxvalue}
                              onClick={RemoveDieClick}
                          />
                      ))}
                      <h3>Total Rolled = {RolledTotal}</h3>
                  </div>

              </header>
         </div>
       );
    }

}

这是我的子组件:

import React from "react";

export default class DiceSelector extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {

        return <button
            className="number"
            onClick={() => this.props.onClick(this.props.dicetype)}
        >
            <img src={require(`../images/${this.props.imagename}`)} alt={this.props.imagename} />
        </button>
    }
}

2 个答案:

答案 0 :(得分:0)

您可以在key组件的状态下存储App,并在每次更新要在

传递子组件的道具时使用不同的key
              <DiceSelector
                      key= { this.state.key+ offset + index} // insted of {"typeList" + index}
                      dicetype={dice.dicetype}
                      imagename={dice.imageName}
                      maxvalue={dice.maxvalue}
                      onClick={AddDieClick} // or onClick={RemoveDieClick}
                  />

                 // offset is used to escape duplicate elements next time when child component will render
                // offset is the length of the array on that you are mapping

您可以在clickHandler方法中添加key的更新逻辑
这将重新呈现子组件。
或者,您可以使用componentWillReceiveProps方法在道具更改时更新子组件的状态。

答案 1 :(得分:0)

我在这里有几处错误。我意识到当我更新列表时不需要刷新孩子,而我需要刷新应用组件。另外,我在应用程序类外部声明了函数functionName(){},而不在函数类中声明了functionName =()= {}。这使我无法正确访问this.state。最后,我绑定到DiceToRollList而不是this.sate.DiceToRollList。这是我更新应用程序组件的方法。

import React, { Component } from 'react';

import './App.scss';

import DiceSelector from "./components/DiceSelector";
import ListOfDiceTypes from "./shared/list-available-dice";

const DiceToRollList = [];
const RolledTotal = 45;

DiceToRollList.push(ListOfDiceTypes[4]);
DiceToRollList.push(ListOfDiceTypes[4]);
DiceToRollList.push(ListOfDiceTypes[3]);

const offset1 = 100;
const offset2 = 500;

export default class App extends Component {
    constructor(props) {
        super(props);
        this.state = { DiceToRollList }
    }

    render() {
     return (
          <div className="App">
              <header className="App-header">
                  <div className="Dice-Box">
                      <h2>Select Dice to Roll</h2>
                      {ListOfDiceTypes.map((dice, index) => (
                          <DiceSelector
                              key={ListOfDiceTypes.length + index} // insted of {"typeList" + index}
                              dicetype={dice.dicetype}
                              imagename={dice.imageName}
                              maxvalue={dice.maxvalue}
                              onClick={this.AddDieClick}
                          />
                      ))}
                  </div>
                  <div className="Dice-Box">
                      <h2>Selected Dice</h2>
                      {this.state.DiceToRollList.map((dice, index) => (
                          <DiceSelector
                              key={this.state.DiceToRollList.length + offset2 + index} // insted of {"dieToRollList" + index}
                              dicetype={dice.dicetype}
                              imagename={dice.imageName}
                              maxvalue={dice.maxvalue}
                              onClick={this.RemoveDieClick}
                          />
                      ))}
                      <h3>Total Rolled = {RolledTotal}</h3>
                  </div>

              </header>
        </div>
      );
    }

    // Functions 
    AddDieClick = (diceType) => {

        let RowToAdd = ListOfDiceTypes.findIndex(obj => {
            return obj.dicetype === diceType
        });

        DiceToRollList.push(ListOfDiceTypes[RowToAdd]);
        this.reSetState();
    }

    reSetState = () => {
        this.setState({ DiceToRollList });
    };

    RemoveDieClick = (diceType) => {

        let DieToAdd = DiceToRollList.findIndex(obj => {
            return obj.dicetype === diceType
        });

        DiceToRollList.splice(DiceToRollList[DieToAdd], 1);
        this.reSetState();

    }

}