Реагировать JS: вызов метода дочернего компонента в родительском компоненте (Реагировать с машинописью) - PullRequest
1 голос
/ 20 марта 2019

Я пытаюсь создать пользовательский компонент выбора номера и пытаюсь добавить его в компоненты там, где это необходимо.Но когда я пытаюсь получить значение выбора чисел в родительском компоненте, я получаю более старое значение.Может ли кто-нибудь помочь мне с этим?

Компонент выбора чисел

import * as React from "react";

interface IState {
  value: number;
}

interface IProps {
  setValue(val: number): void;
}

class NumberPicker extends React.Component<IProps, IState> {
  constructor(props: any) {
    super(props);
    this.state = {
      value: 0
    };
  }

  public doDecrement = () =>
    // DECREMENT CODE
    {
      if (this.state.value < 1) {
        console.log("LESS THAN O");
      } else {
        this.setState({
          value: this.state.value - 1
        });
        this.props.setValue(this.state.value);
      }
    };

  public doIncrement = () =>
    // INCREMENT CODE
    {
      this.setState({
        value: this.state.value + 1
      });
      this.props.setValue(this.state.value);
    };

  public handleChange = (
    e: React.ChangeEvent<HTMLInputElement> // CHANGE HANDLER
  ) => {
    const val = parseInt(e.target.value);
    this.setState({ value: val });
  };

  public render() {
    return (
      <div>
        <button
          onClick={this.doDecrement}
          className="fa fa-minus fa-inverse fa-2x"
        />
        <input
          type="text"
          className="number"
          value={this.state.value}
          onChange={this.handleChange}
        />
        <button
          onClick={this.doIncrement}
          className="fa fa-plus fa-inverse fa-2x"
        />
      </div>
    );
  }
}
export default NumberPicker;

КОД РОДИТЕЛЯ КОМПОНЕНТА

import * as React from "react";
import NumberPicker from "./NumberPicker";

interface IState {
  val: number;
}

interface IProps {}

class Parent extends React.Component<IProps, IState> {
  constructor(props: any) {
    super(props);
    this.state = {
      val: 0
    };
  }

  handleVal = (value: number) => {
    this.setState({ val: value }, () => console.log(this.state.val));
  };

  render() {
    return (
      //Some fields along with the below numberpicker
      <NumberPicker setValue={this.handleVal} />
    );
  }
}

export default Parent;

Я также пытался использовать функцию обратного вызова setState, но это не помоглоне похоже на работу.Родительский компонент всегда показывает старшее значение. Как я могу получить обновленное значение NumberPicker внутри родителя?Помощь будет оценена!

Ответы [ 3 ]

0 голосов
/ 20 марта 2019

setState не является синхронной функцией.Поэтому, когда вы вызываете обратный вызов от родителя, вы вызываете его со старым значением состояния, потому что новое значение будет установлено когда-то в будущем.Вы можете вызвать обратный вызов с тем же значением, которое вы устанавливаете для установки: this.state.value - 1 или this.state.value + 1. Он должен работать как положено.Я также рекомендую прочитать , думая о реакции , чтобы лучше понять, где вы должны держать свое состояние.

0 голосов
/ 20 марта 2019

Не используйте состояние для передачи значений в обратном вызове, вы можете сделать так: -

  handleChange = (
    e: React.ChangeEvent<HTMLInputElement> // CHANGE HANDLER
  ) => {
    const val = parseInt(e.target.value);
    // this.setState({ value: val });
    this.props.setValue(val);
  };

Надеюсь, это поможет!

0 голосов
/ 20 марта 2019

React setState является асинхронным, и из-за этого this.props.setValue будет вызвана функция до того, как setState обновит ваше состояние в дочернем компоненте Numberpicker. Вот почему старое значение передается родительскому компоненту.

Вместо этого вы можете вызвать this.props.setValue внутри функции обратного вызова setState.

 public doIncrement = () =>
    // INCREMENT CODE
    {
      this.setState({
        value: this.state.value + 1
      }, () => {
              this.props.setValue(this.state.value);
         });

    };
public doDecrement = () =>
    // DECREMENT CODE
    {
      if (this.state.value < 1) {
        console.log("LESS THAN O");
      } else {
        this.setState({
          value: this.state.value - 1
        }, () => {
              this.props.setValue(this.state.value);
           });
      }
    };
...