#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
внутри нее, а не в других функциях. В противном случае проблема сохраняется.