Реагирует на неправильные результаты операций с числами

#reactjs #visual-studio-code #operators

#reactjs #visual-studio-code #операторы

Вопрос:

Я новичок в React, и я работаю в простом приложении, и мне нужно прочитать некоторые числа и выполнить операции с ними. Проблема в том, что я всегда получаю нечетные результаты. Например, при отладке я получил:

 CALCULANDO 8 * 4 = 64
CALCULANDO 8 * 2 = 64
CALCULANDO 8 * 23 = 64
CALCULANDO 1 * 23 = 1
CALCULANDO 1 * 2 = 1
CALCULANDO 12 * 2 = 144
CALCULANDO 1 * 2 = 1
CALCULANDO 1 * 2 = 1
  

Глядя на результат, я предполагаю, что значения te хорошо считываются, и я проверил, что я жду завершения setState, но я не могу понять проблему. Полный код:

 import Distribution from './Distribution';
import React, {Component} from 'react'; 
import NumberField from '../Components/NumberField';

class Binomial extends Component {
    constructor (props) {
      super(props);
      this.changeN = this.changeN.bind(this);
      this.changeP = this.changeP.bind(this);

      this.state={
        name: "Binomial",
        p: 0,
        n: 0,
        media: 0,
        varianza: 0
      }
    }

    calcularTodo(){
      this.calcularMedia();
      this.calcularVarianza();
    }

    calcularMedia(){
      if(this.state.p === 0|| this.state.n === 0)
        this.setState({media: 0})

      else{
        let result = Number(this.state.n) * Number(this.state.n); 
        console.log("CALCULANDO "   this.state.n   " * "   this.state.p   " = "   result)

        this.setState({media: result})
      }
    }

    calcularVarianza(){
      this.setState({varianza: 2})
    }

    render(){
      return(
        <div>
          <NumberField label={"p"} handleChange={this.changeP}/>
          <NumberField label={"n"} handleChange={this.changeN}/>
          <Distribution name={this.state.name} media={this.state.media} varianza={this.state.varianza}/>
        </div>
      )
    }

    changeP = async function (event){
      await this.setState({p: Number(event.target.value)});
      this.calcularTodo();
    }

    changeN = async function (event){
      await this.setState({n: Number(event.target.value)});
      this.calcularTodo();
    }
}

export default Binomial;
  

Другие модули:

 import React, {useState, Component} from 'react';
import {TextField} from "@material-ui/core";


class NumberField extends Component{
    
    render(){ 
        return (
        <TextField
          label="None"
          id="margin-none"
          label={this.props.label}
          variant="outlined"
          type={Number}
          onChange={this.props.handleChange}
        />
        )
    }
}

export default NumberField;
  

и

 import React, {Component} from 'react'; 
import {Table} from '../Components/Table'
import NumberField from '../Components/NumberField'


class Distribution extends Component{
 
  constructor () {
    super();
  }

  render(){
    
    return(
      <div> 
      <this.props.name/>
      <Table _media={this.props.media} _varianza={this.props.varianza}/>
      </div>
    )
  }

}

export default Distribution;
  

Я ценю любую помощь. Спасибо.

Комментарии:

1. вам нужно сделать это таким образом janhesters.com/updater-functions-in-setstate

2. Спасибо за ответ. Вы имеете в виду что-то вроде state = {...prevState, ...{...prevState, media: result},}; ? Я получаю сообщение об ошибке: 'prevState' is not defined no-undef . Почему я должен делать это именно так, а не просто использовать await? Это кажется немного сложным.

Ответ №1:

Если взглянуть на это со второй стороны, я думаю, что состояния slate — это не проблема, проблема в том, что вы пытаетесь вычислить значения, которые зависят от других, и обновлять их сразу, поскольку обновления состояния react batches будут принимать предыдущие значения для вычислений. Вы можете решить это 2 способами, создав функцию обновления или используя componentDidUpdate

функция обновления

 class Binomial extends Component {
  ...

  updateState(updates) {
    this.setState(prevState => {
      const newState = { ...prevState, ...updates };
      return {
        ...newState,
        media: this.calcularMedia(newState),
        varianza: this.calcularVarianza(),
      };
    });
  }

  calcularMedia(state) {
    if (state.p === 0 || state.n === 0) return 0;

    let result = Number(state.n) * Number(state.n);
    console.log('CALCULANDO '   state.n   ' * '   state.p   ' = '   result);

    return resu<
  }

  calcularVarianza() {
    return 2;
  }

  render() {
    ...
  }

  changeP = async function(event) {
    await this.updateState({ p: Number(event.target.value) });
  };

  changeN = async function(event) {
    await this.updateState({ n: Number(event.target.value) });
  };
}
  

componentDidUpdate

 class Binomial extends Component {
  ...

  componentDidUpdate(_prevProps, prevState) {
    if (prevState.p !== this.state.p || prevState.n !== this.state.n) {
      this.calcularTodo();
    }
  }

  calcularTodo() {
    this.calcularMedia();
    this.calcularVarianza();
  }

  calcularMedia() {
    if (this.state.p === 0 || this.state.n === 0) this.setState({ media: 0 });
    else {
      let result = Number(this.state.n) * Number(this.state.n);
      console.log('CALCULANDO '   this.state.n   ' * '   this.state.p   ' = '   result);

      this.setState({ media: result });
    }
  }

  calcularVarianza() {
    this.setState({ varianza: 2 });
  }

  render() {
    ...
  }

  changeP = async function(event) {
    await this.setState({ p: Number(event.target.value) });
  };

  changeN = async function(event) {
    await this.setState({ n: Number(event.target.value) });
  };
}
  

Комментарии:

1. Если это кому-нибудь поможет, я обнаружил, что в componentDidUpdate версии лучше использовать this.setState внутри нее, а не в других функциях. В противном случае проблема сохраняется.