使用 ReactJS 创建可调计时器时遇到问题,将子项的状态更改为父项

Having trouble creating an adjustable timer using ReactJS, changing state of a child item to parent

CodeSandbox example of my code

我正在尝试制作一个定时器应用程序,它具有独特的 UI 定时器。我的问题是我似乎无法在不出现故障的情况下调整计时器。

当我尝试缩短时间时,它会在“箭头”按钮下添加一个新数字。而不是这样做,它应该减去上面的数字。

如果单击向上箭头,时间将变为 1,但如果我们单击向下箭头,时间应返回到 0。现在计时器仅上升到 1,这很好为了这个问题的目的。

我知道我做错了什么,但我似乎无法理解。我真的很想能够使用我设置的两个组件来做到这一点,只是为了保持代码的可维护性。

两个重要的组成部分是:

TimerSettings.jsx,以及Arrows.jsx

CodeSandbox example of my code

import React, { Component } from "react";
import Arrows from "./Arrows";
class TimerSettings extends Component {
    constructor(props) {
        super(props);
        this.state = { timeData: 0 };
    }
    render() {
        let changeTime = ["up", "up", "up", "up", "up", "up", "down", "down", "down", "down", "down", "down"];

        return (
            <React.Fragment>
                <div className="container">
                    <div className="row">
                        <div className="col s12" id="timer-settings-block">
                            <h1 className="center-align" id="timer-settings-title">
                                Create Timer
                            </h1>
                            {changeTime.map((item, uid) => (
                                <Arrows status={item} uid={uid} timeData={this.state.timeData} /*changeTime={() => this.handleTime()}*/ />
                            ))}
                        </div>
                    </div>
                </div>
            </React.Fragment>
        );
    }
    handleTime = () => {
        this.setState({ timeData: 1 });
    };
}

export default TimerSettings;

Arrows.jsx - 子组件

import React, { Component } from "react";

class Arrows extends Component {
    constructor(props) {
        super(props);
        this.state = { flip: "1", timeData: 0 };
        this.posTime = React.createRef();
        this.negTime = React.createRef();
    }

    render() {
        return (
            <p className="center-align">
                <div className="col s2">
                    <div className="col s6">
                        <h4
                            style={{ transform: "scaley(" + this.state.flip + ")" }}
                            className="move-time"
                            id={"move-first-" + this.props.uid}
                            ref={this.negTime + this.props.uid}
                            /*onClick={this.props.changeTime}*/
                            onClick={this.handleTime}
                        >
                            ^
                        </h4>
                        <h3>{this.state.timeData}</h3>
                    </div>
                </div>
            </p>
        );
    }

    handleTime = () => {
        this.setState({ timeData: 1 });
        if (this.state.flip === "-1") {
            this.setState({ timeData: 0 });
        }
    };

    componentDidMount = () => {
        if (this.props.status === "down") {
            this.setState({ flip: "-1", timeData: null });
        }
    };
}

export default Arrows;

您需要在 Arrow 组件中渲染向上和向下箭头,这样向上和向下箭头可以产生相同的状态。

class Arrows extends Component {
  constructor(props) {
    super(props);
    this.state = { timeData: 0 };
    this.posTime = React.createRef();
    this.negTime = React.createRef();
  }

  handleTime = (val) => () => {
    this.setState((prevState) => ({
      timeData: prevState.timeData + val
    }));
  };

  render() {
    return (
      <p className="center-align">
        <div className="col s2">
          <div className="col s6">
            <h4
              className="move-time"
              id={"move-first-" + this.props.uid + "-up"}
              ref={this.posTime}
              onClick={this.handleTime(1)}
            >
              ^
            </h4>
            <h3>{this.state.timeData}</h3>
            <h4
              style={{ transform: "scaley(-1)" }}
              className="move-time"
              id={"move-first-" + this.props.uid + "-down"}
              ref={this.negTime}
              onClick={this.handleTime(-1)}
            >
              ^
            </h4>
          </div>
        </div>
      </p>
    );
  }
}

而不是渲染 12(6 up/6 向下)你只渲染一个包含 6 Arrow 个组件的数组。

class TimerSettings extends Component {
  constructor(props) {
    super(props);
    this.state = { timeData: 0 };
  }

  handleTime = () => {
    this.setState({ timeData: 1 });
  };

  render() {
    let changeTime = [...Array(6).keys()];

    return (
      <React.Fragment>
        <div className="container">
          <div className="row">
            <div className="col s12" id="timer-settings-block">
              <h1 className="center-align" id="timer-settings-title">
                Create Timer
              </h1>
              {changeTime.map((item, uid) => (
                <Arrows
                  key={uid}
                  status={item}
                  uid={uid}
                  timeData={this.state.timeData}
                />
              ))}
            </div>
          </div>
        </div>
      </React.Fragment>
    );
  }
}