状态更改后,React Compoment不更新

时间:2018-06-21 13:51:51

标签: javascript node.js reactjs

我有一个问题,当我的状态在makeNewSmallThings中更改时,我的render方法不会更新组件,您能帮我吗?我将要呈现的代码主要是显示重要部分 代码:

constructor(props){
    super(props)
    this.smallElements = {}
    this.handleConsume = this.handleConsume.bind(this)
    this.makeNewSmallThings = this.makeNewSmallThings.bind(this)
    this.onSmallThingSpawn = this.onSmallThingSpawn.bind(this)
    let arrayOfSmallThings = this.getInitialiceArray()
    let arrayOfObjects = this.getSmallItems(arrayOfSmallThings)
    this.state = {smallThings: arrayOfSmallThings, objects: arrayOfObjects}
    this.makeNewSmallThings()

    console.log(arrayOfSmallThings)
}
makeNewSmallThings(){
    let arrayOfSmallThings = this.state.smallThings
    let arrayOfObjects = this.state.objects
    let newId = arrayOfSmallThings[arrayOfSmallThings.length - 1] + 1
    let newObject = this.createSmallThing(newId,newId)
    arrayOfSmallThings.push(newId)
    arrayOfObjects.push(newObject)
    this.setState({smallThings: arrayOfSmallThings, objects: arrayOfObjects})
    console.log(this.state.objects)
    setTimeout(this.makeNewSmallThings, 1000)
}
render(){
    return (
        <div className="Game">
            <Player />
            {this.state.objects}
        </div>
    )
}

1 个答案:

答案 0 :(得分:0)

您使用setState的方式不正确。您可以直接更改状态,然后使用setState将状态内的数组设置为它们已经具有的值。

要解决此问题,请先更改数组的副本,然后再更改副本,然后将更改后的副本传递到setState来更改状态。

违规行

let arrayOfSmallThings = this.state.smallThings
let arrayOfObjects = this.state.objects

应更改为

let arrayOfSmallThings = [...this.state.smallThings]
let arrayOfObjects = [...this.state.objects]

示例

要运行此示例

  1. 使用 create-react-app 创建一个React应用。
  2. 更改App.jsindex.js以匹配下面的代码。
  3. npm start

App.js

import React, { Component } from 'react';

class Player extends Component {
    render() {
        return (
            <p>Player</p>
        )
    }
}

class App extends Component {
    constructor(props){
        super(props)
        this.smallElements = {}
        this.handleConsume = this.handleConsume.bind(this)
        this.makeNewSmallThings = this.makeNewSmallThings.bind(this)
        this.onSmallThingSpawn = this.onSmallThingSpawn.bind(this)
        let arrayOfSmallThings = this.getInitialiceArray()
        let arrayOfObjects = this.getSmallItems(arrayOfSmallThings)
        this.state = {smallThings: arrayOfSmallThings, objects: arrayOfObjects}
        this.makeNewSmallThings()

        console.log(arrayOfSmallThings)
    }

    handleConsume() {
        console.log('handleConsume')
    }
    onSmallThingSpawn = e => {
        console.log(e)
    }
    getInitialiceArray() {
        return [0]
    }
    getSmallItems(array) {
        return array.map(item => (<span key={item}> {item} </span>))
    }

    makeNewSmallThings(){
        let arrayOfSmallThings = this.state.smallThings // Change me to [...this.state.smallThings]
        let arrayOfObjects = this.state.objects // Change me to [...this.state.objects]
        let newId = arrayOfSmallThings[arrayOfSmallThings.length - 1] + 1
        let newObject = this.createSmallThing(newId,newId)
        arrayOfSmallThings.push(newId)
        arrayOfObjects.push(newObject)
        this.setState({smallThings: arrayOfSmallThings, objects: arrayOfObjects})
        console.log(this.state.objects)
        setTimeout(this.makeNewSmallThings, 1000)
    }

    createSmallThing(id, id2) {
        return (
            <span key={id}> {id2} </span>
        )
    }

    render(){
        return (
            <div className="Game">
                <Player />
                {this.state.objects}
            </div>
        )
    }
}

export default App

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'

ReactDOM.render(<App />, document.getElementById('root'))

更改App.js中带有注释的行,以查看该应用程序从无法运行变为正在运行。