Får fel färger på mina components i React när jag lägger till dem i en array

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Sep 2013

Får fel färger på mina components i React när jag lägger till dem i en array

Jag försöker göra så att rätt angivet tal från min multiplikation blir skrivet i grön text och fel svar blir skrivet i röd text men jag har ett problem.

Första svaret blir alltid i rött och andra svaret blir färgen från första frågan. Så om jag svarat rätt på första frågan så blir andra frågans text grön osv. Det känns som att min state inte hinner uppdateras innan komponenten läggs i min array.

Sen undrar jag hur jag ska kunna lägga min array som en const istället i programmet så att jag kan skicka in alla svar där, och i slutet av programmet lägga upp hela arrayen i staten.

Tack på förhand.

import React, { Component } from 'react'; import { Container, Row, Button, Col, ProgressBar, Modal } from 'react-bootstrap'; import './Multiplication.css' export default class Multiplication extends Component { state = { numberOne: null, numberTwo: null, numberToCheck: null, correct: null, correctAnswer: 0, wrongAnswer: 0, answered: 0, modalShow: false, checkIt: true, start: false, answers: [] } generateNumbers = () => { const one = Math.floor(Math.random() * 13); const two = Math.floor(Math.random() * 13); this.setState({numberOne: one, numberTwo: two, start: true, checkIt: false }); } checkAnswer = () => { const numberToCheck = parseInt(document.getElementById("answer").value, 10); const { numberOne, numberTwo} = this.state; const isCorrect = (numberOne * numberTwo) === numberToCheck; isCorrect ? this.setState({ correctAnswer: this.state.correctAnswer + 1, correct: true }) : this.setState({ wrongAnswer: this.state.wrongAnswer + 1, correct: false }); this.state.answers.push(<Answer isCorrectAnswer={ this.state.correct } numberOne={ this.state.numberOne } numberTwo={ this.state.numberTwo }/>); this.setState({ answers: answers }); document.getElementById("answer").value = ""; document.getElementById("checker").innerHTML = isCorrect; this.setState({ answered: this.state.answered + 1 }); if (this.state.answered === 9) { this.setState({modalShow: true }); } this.generateNumbers(); } render() { let modalClose = () => this.setState({ modalShow: false, correctAnswer: 0, wrongAnswer: 0, numberOne: null, numberTwo: null, answered: null, start: false, checkIt: true, answers: []}); return ( <Container> <Col xs={12}> <Row className="justify-content-center"> <Button id="start" disabled={ this.state.start } onClick={ this.generateNumbers }>Start</Button> </Row> </Col> <Row className="justify-content-center"> <h1 id="numberOne">{ this.state.numberOne }</h1> <h1>&nbsp;x&nbsp;</h1> <h1 id="numberTwo">{ this.state.numberTwo }</h1> </Row> <Row className="justify-content-center"> <input id="answer" type="number" /> </Row> <Row className="justify-content-center"> <Button id="check" disabled={ this.state.checkIt } onClick={ this.checkAnswer }>Check</Button> </Row> <Row className="justify-content-center"> <p>{ this.state.wrongOrRight }</p> </Row> <Row className="justify-content-center m-2"> <ProgressBar max="10"> <ProgressBar max="10" striped variant="success" animated now={ this.state.correctAnswer } key={1} /> <ProgressBar max="10" striped variant="danger" animated now={ this.state.wrongAnswer } key={2} /> </ProgressBar> </Row> <Row className="justify-content-center"> <p id="checker"></p> </Row> <Modal size="sm" show={ this.state.modalShow } onHide={ modalClose } > <Modal.Header closeButton> <Modal.Title> Your score </Modal.Title> </Modal.Header> <Modal.Body> <p>Correct Answers: { this.state.correctAnswer }</p> <p>Wrong Answers: { this.state.wrongAnswer }</p> <ul> { this.state.answers.map( (tag, index) => <li key={index}>{tag}</li>)} </ul> </Modal.Body> </Modal> </Container> ); } } const Answer = props => ( <div style={{color: `${props.isCorrectAnswer ? 'green' : 'red'}`}}>{props.numberOne} x {props.numberTwo} = {props.numberOne * props.numberTwo}</div>);

i7 4790k | Asus Z97M-Plus | 16gb ram | Asus Strix 970 | Phanteks PH-TC14PE | Samsung 850 Evo 250gb | Corsair Force GS 120gb | Fractal Design Integra M 650w | Fractal Design Define Mini C

https://my-homepage-43a9e.firebaseapp.com/

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Aug 2013

setState sker async, så den kommer alltid hamna efter då this.state inte hunnit uppdateras då du kör render.

Finns två sätt att lösa det på.
setState tar en callback som du kan skicka in och köra direkt efter, då kommer this.state vara det nya värdet.

Ett annat sätt att hantera det är med componentDidUpdate, som kommer att köras efter varje rendering. Där kan du jämföra prevState med this.state och isf anropa din metod om du behöver det. Detta bör du kombinera med shouldcomponentupdate, som returnar en bool.

Angående const för en array vet jag inte hur du menar. Du måste hantera det i ett state någonstans så att det finns tillgängligt i clienten. Du skulle dock kunna spara ner dina svar i en array i en session eller cookie. Det kan du komma åt överallt i clienten vid behov.
Du skulle iofs kanske kunna lägga en const array i en egen fil med en export tag och importa den i de componenterna där du behöver den, har inte testat. Låter dock väldigt onödigt.

Skickades från m.sweclockers.com

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Sep 2013
Skrivet av zaibuf:

setState sker async, så den kommer alltid hamna efter då this.state inte hunnit uppdateras då du kör render.

Finns två sätt att lösa det på.
setState tar en callback som du kan skicka in och köra direkt efter, då kommer this.state vara det nya värdet.

Ett annat sätt att hantera det är med componentDidUpdate, som kommer att köras efter varje rendering. Där kan du jämföra prevState med this.state och isf anropa din metod om du behöver det. Detta bör du kombinera med shouldcomponentupdate, som returnar en bool.

Angående const för en array vet jag inte hur du menar. Du måste hantera det i ett state någonstans så att det finns tillgängligt i clienten. Du skulle dock kunna spara ner dina svar i en array i en session eller cookie. Det kan du komma åt överallt i clienten vid behov.
Du skulle iofs kanske kunna lägga en const array i en egen fil med en export tag och importa den i de componenterna där du behöver den, har inte testat. Låter dock väldigt onödigt.

Skickades från m.sweclockers.com

Tack så mycket. Men jag tog en annan lösning.

this.setState({ answers: [...this.state.answers, <Answer isCorrectAnswer={ this.state.correct } numberOne={ this.state.numberOne } numberTwo={ this.state.numberTwo }/>] });

ändrade jag till

this.setState({ answers: [...this.state.answers, <Answer isCorrectAnswer={ isCorrect } numberOne={ this.state.numberOne } numberTwo={ this.state.numberTwo }/>] });

Simpelt :/

i7 4790k | Asus Z97M-Plus | 16gb ram | Asus Strix 970 | Phanteks PH-TC14PE | Samsung 850 Evo 250gb | Corsair Force GS 120gb | Fractal Design Integra M 650w | Fractal Design Define Mini C

https://my-homepage-43a9e.firebaseapp.com/