Reputation: 3
I am a beginner in reactjs so please bear with me. I am using state
and setState
in my class component, thing is I want to reference value1
,value2
and value3
properties in setState
inside the answerIsFalse
arrow function as seen in the code below to proposedAnswer
and check
properties in the same setState
instead of currentState
because I want to re-assign their values and pass them to state
. I tried using this
, binding it, and setState.value1
for example but nothing worked.
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
constructor(){
super();
this.setState = this.setState.bind(this);
const value1 = Math.floor(Math.random() * 100);
const value2 = Math.floor(Math.random() * 100);
const value3 = Math.floor(Math.random() * 100);
const proposedAnswer = Math.floor(Math.random() * 3) + value1 + value2 + value3;
const numQuestions = 0;
const numCorrect = 0;
const check = proposedAnswer === value1 + value2 + value3;
this.state = {
value1: value1,
value2: value2,
value3: value3,
proposedAnswer: proposedAnswer,
numQuestions: numQuestions,
numCorrect: numCorrect,
check: check
};
}
answerIsTrue = () => {
console.log(this);
this.setState ((currentState) => ({
numCorrect: currentState.check ? currentState.numCorrect + 1 : currentState.numCorrect,
numQuestions: currentState.numQuestions + 1,
value1: Math.floor(Math.random() * 100),
value2: Math.floor(Math.random() * 100),
value3: Math.floor(Math.random() * 100),
proposedAnswer: Math.floor(Math.random() * 3) + currentState.value1 + currentState.value2 + currentState.value3,
check: currentState.proposedAnswer === currentState.value1 + currentState.value2 + currentState.value3
}))
}
answerIsFalse = () => {
console.log(this);
this.setState ((currentState) => ({
numCorrect: currentState.check ? currentState.numCorrect : currentState.numCorrect + 1,
numQuestions: currentState.numQuestions + 1,
value1: Math.floor(Math.random() * 100),
value2: Math.floor(Math.random() * 100),
value3: Math.floor(Math.random() * 100),
proposedAnswer: Math.floor(Math.random() * 3) + currentState.value1 + currentState.value2 + currentState.value3,
check: currentState.proposedAnswer === currentState.value1 + currentState.value2 + currentState.value3
}))
}
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">ReactND - Coding Practice</h1>
</header>
<div className="game">
<h2>Mental Math</h2>
<div className="equation">
<p className="text">{`${this.state.value1} + ${this.state.value2} + ${this.state.value3} = ${this.state.proposedAnswer}`}</p>
</div>
<button
onClick = {() => this.answerIsTrue()}
>
True
</button>
<button onClick = {() => this.answerIsFalse()}>
False
</button>
<p className="text">
Your Score: {this.state.numCorrect}/{this.state.numQuestions}
</p>
</div>
</div>
);
}
}
export default App;
Upvotes: 0
Views: 1067
Reputation: 1709
As I understand, you may be having a misconception of how state
and setState
works.
The state
object is supposed to be immutable, so to "modify" it you need to re-write it every time. For example:
this.state = { age: 25, name: 'John' }
To change the age
attribute, you need to use setState()
and pass it a new state
object.
this.setState({ ...this.state, age: 30}) // {age: 30, name: 'John'}
In this case this.state
is giving me access to the current state and all its attributes as they were defined before. To make it more clear:
let newState = { ...this.state, age: 30}
this.setState(newState) // {age: 30, name: 'John'}
Keep in mind you never have to overwrite this.state
but always create a new object and pass it to this.setState()
as an argument to be able to modify a component state.
Check out the React's state docs and the spread operator docs.
Also, it seems that your answerIsFalse
and answerIsTrue
methods share a lot of code and you may want to refactor them.
Some of that code can be reused if you put it in its own method, for example:
Math.floor(Math.random() * 100)
You could do something like this:
const getRandomValue = (factor) => {
return Math.floor(Math.random() * factor)
}
And then use it like this: this.getRandomValue(100)
or this.getRandomValue(3)
when you need them.
Also, the names are a bit confusing (to me, at least) as may imply that the methods return boolean values but in reality are changing the component's state. I would rename them to something like setAnswerToFalse
or something like that.
Upvotes: 1