为什么我用对象传播覆盖状态下的所有值?

时间:2019-01-20 17:46:17

标签: reactjs object ecmascript-6 setstate

在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>

        )
    }

}

我的结果是一个selectedCountry,但是从countryFlags数组中有一组全新的随机选择国家。

1 个答案:

答案 0 :(得分:1)

更改状态很简单:

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)
    ] : ""

因此,您的UI将会更改。

如果属性和状态未更改,

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 })
});