Почему я перезаписываю все свои значения в состоянии с моим распространением объекта? - PullRequest
0 голосов
/ 20 января 2019

В моей функции handleChange я использую объектный спред, чтобы получить все предыдущие ключи / значения из this.state, и добавляю новое значение к ключу selectedCountry.Моя проблема в том, что я продолжаю переназначать значение countryFlags, которое портит состояние моего приложения.Я что-то пропустил?Я действительно боролся с этим часами, и я не могу понять причину этого.Это моя общая реализация setState.Заранее благодарим вас за наблюдение.

import React, {Component} from "react"
import FlagSelect from "./FlagSelect";


export default class FlagQuiz extends Component   {  
    constructor()  {
        super()
        this.state = {
            countryFlags: undefined,
            selectedCountry: ""
        }
        this.handleChange = this.handleChange.bind(this)
    }

    componentDidMount(){
        fetch("https://restcountries.eu/rest/v2/all")
            .then(function(response, reject) { 
                return response.json()
            })
            .catch(() => console.log("nope"))
            .then((data) => {
                this.setState({countryFlags: data})
            });

    }

    handleChange(event){
        event.preventDefault();
        const {name, value, type, checked} = event.target
        // console.log(this.state)
        const newState = {...this.state}
        newState.selectedCountry = value
        // console.log(newState)

        ///STOP UPDATING THE countryFlgs!!
        this.setState({...this.state, selectedCountry: value})
        console.log(this.state)

    }

    render(){
        const flagStyle = {
            display: "block",
            marginLeft: "auto",
            marginRight: "auto",
            width: "50%"
        }
        const src = this.state.countryFlags === undefined ? "" : this.state.countryFlags[0].flag
        const buttonStye = {
            background:"lightblue",
            color: "white",
            fontSize: "30px",
            float: "right"
        }
    const countries = this.state.countryFlags ? [
            Math.floor(Math.random() * this.state.countryFlags.length),
            Math.floor(Math.random() * this.state.countryFlags.length),
            Math.floor(Math.random() * this.state.countryFlags.length),
            Math.floor(Math.random() * this.state.countryFlags.length)
        ] : ""

        const fourCountries = () => {
            let flagselects = countries ? countries.map((countrynum) =>{
                return <FlagSelect 
                handleChange={this.handleChange} 
                checked={this.state.selectedCountry}
                key={countrynum}
                countryinfo={this.state.countryFlags[countrynum].name}/>
            }) : null

            return flagselects
        }

        return (
            <div>
            <form>
                <div className="form-check">
                {fourCountries()}
                <div className="form-group">
                <button style={buttonStye} >Guess</button>
                </div>
                </div>
            </form>

                <h1 style={{textAlign:"center"}}>Flag Quiz</h1>
                <img src={src} alt="flag" style={flagStyle}
                />
                {this.state.countryFlags ? console.log(this.state.countryFlags.length): ""}
            </div>

        )
    }

}

Мои результаты являются выбранной страной, но с совершенно новым набором рандомизированного выбора стран из массива countryFlags.

1 Ответ

0 голосов
/ 20 января 2019

Изменить состояние просто:

this.setState({ selectedCountry: value })

Больше ничего не нужно.

Однако изменение состояния всегда приводит к повторному отображению. И я вижу большую проблему с вашим рендерингом.

Каждый раз, когда вызывается render, вы будете рандомизировать свои флаги:

    const countries = this.state.countryFlags ? [
        Math.floor(Math.random() * this.state.countryFlags.length),
        Math.floor(Math.random() * this.state.countryFlags.length),
        Math.floor(Math.random() * this.state.countryFlags.length),
        Math.floor(Math.random() * this.state.countryFlags.length)
    ] : ""

Поэтому ваш интерфейс изменится.

Render должен всегда возвращать одно и то же, если свойства и состояние не изменились. Тем не менее, ваш render всегда будет отображать разные вещи в зависимости от случайных чисел.

Вы должны переместить рандомизацию в ваше состояние, например:

.then((data) => {
    const countries = [
         Math.floor(Math.random() * data.length),
         Math.floor(Math.random() * data.length),
         Math.floor(Math.random() * data.length),
         Math.floor(Math.random() * data.length)
    ]
    this.setState({ countryFlags: data, countries })
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...