首页 > 解决方案 > 如何在 React Js 中单独更新一个子组件

问题描述

我正在制作游戏宾果游戏的反应版本。我添加了 25 个按钮,它们是子组件。最初我在每个按钮中都有空值。然后在每次点击时,我试图将点击按钮的值从 1 更新到 25。但是当我点击一个按钮来更新按钮标签时,所有按钮的值都会更新。任何人都可以提出这背后的原因吗?

应用程序.js

import React from "react";
import "./styles.css";
import GameContainerOne from "./GameContainerOne";

export default function App() {
  return (
    <div className="App">
      <GameContainerOne />
    </div>
  );
}

GameContainerOne.js

import React from "react";
import ButtonBox from "./ButtonBox";

class GameContainerOne extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      btnLabel: 0
    };
  }
  handleClicked = () => {
    if (this.state.btnLabel < 25) {
      this.setState({ btnLabel: ++this.state.btnLabel });
      console.log("after", this.state.btnLabel);
    }
  };
  render() {
    let menuItems = [];
    let key = 0;
    for (let i = 0; i < 5; i++) {
      for (let j = 0; j < 5; j++) {
        let index = "" + i + j;
        // console.log(index)
        key++;
        menuItems.push(
          <ButtonBox
            key={key}
            index={index}
            value={this.state.btnLabel}
            handleClicked={this.handleClicked.bind(this)}
          />
        );
      }
    }
    return <div className="wrapper">{menuItems}</div>;
    // this.handleButtonBox()
  }
}
export default GameContainerOne;

按钮框.js

import React from "react";
import Button from "@material-ui/core/Button";

class ButtonBox extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      initialBtnColor: "Default",
      selectedBtnColor: "Primary"
    };
  }

  handleClick = () => {
    // console.log("before",this.state.btnLabel)

    this.setState({ initialBtnColor: "Primary" });
    return this.props.handleClicked;
  };

  render() {
    console.log("Key=", this.props);
    //   const { index } = this.props.index;
    console.log("Key=", this.props.index);
    return (
      <div>
        <Button
          variant="contained"
          color={this.state.initialBtnColor}
          onClick={this.props.handleClicked}
        >
          {this.props.value}
        </Button>
      </div>
    );
  }
}
export default ButtonBox;

请找到代码框链接: https ://codesandbox.io/s/bingo-game-glk8v

标签: javascriptreactjsreact-component

解决方案


btnLabel状态移动到ButtonBox.

示例(使用钩子):

// ButtonBox.js

import React from "react";
import Button from "@material-ui/core/Button";

function ButtonBox(props) {
  const [buttonColor, setButtonColor] = React.useState("Default");
  const [value, setValue] = React.useState(props.startValue);
  return (
    <div>
      <Button
        variant="contained"
        color={buttonColor}
        onClick={() => {
          setValue(value + 1);
          setButtonColor("Primary");
          props.handleClicked(props.index);
        }}
      >
        {value}
      </Button>
    </div>
  );
}

export default ButtonBox;

// GameContainerOne.js

import React from "react";
import ButtonBox from "./ButtonBox";

function GameContainerOne(props) {
  const handleClicked = React.useCallback(btnIndex => {
    // Called after a button is clicked
  }, []);
  let menuItems = [];
  let key = 0;
  for (let i = 0; i < 5; i++) {
    for (let j = 0; j < 5; j++) {
      let index = "" + i + j;
      key++;
      menuItems.push(
        <ButtonBox
          key={key}
          index={index}
          startValue={0}
          handleClicked={handleClicked}
        />
      );
    }
  }
  return <div className="wrapper">{menuItems}</div>;
}

export default GameContainerOne;


推荐阅读