状态似乎未正确更新

时间:2020-06-13 17:17:24

标签: javascript reactjs

我正在尝试列出我看过的《星球大战》电影。我希望能够检查和取消选中我单击的内容,并通过localStorage保存它。 出于某种原因,有时,如果我一次跨过一部电影,则刷新页面后,只有跨过的最后一部电影仍会跨过。我尝试使用控制台进行调试,但发现故障出在我的状态上。有时,当我单击多个元素后,其中一些元素将变为假,而不是变为真。

这是我的代码:

import React from 'react';
export default class Movie extends React.Component{
    constructor(props){
        super()
        this.state = (localStorage.appState) ? JSON.parse(localStorage.appState)
        : { 0: false, 1: false, 2: false, 3: false, 4: false, 5: false};
    }

    clickedTitle = (event) => {
        if (event.target.tagName === "SPAN") {
            this.setState({
                [event.target.id]: !this.state[event.target.id]
            }, () => {
                localStorage.setItem('appState',JSON.stringify(this.state))
            });
                // localStorage.clear()

            }
        }
        render(){

            return(
                <div className="sw_title"  onClick={this.clickedTitle}>
                <span id={this.props.index} className={`${this.state[this.props.index] ? "clicked" : "not-clicked"}`}> {this.props.title} </span>
                </div>
                );
            }
        }

在此先感谢您的宝贵时间! 四月

2 个答案:

答案 0 :(得分:1)

React应用程序中发生任何更改的数据应该有一个单个“事实来源” ,并且您在每个Movie组件中重复appState会导致应用程序状态不一致。< / p>

您应该做的是提升状态。换句话说,将该状态和clickedTitle函数移至其父组件,并将clickedTitle作为prop传递给Movie Component。 (或者您可以使用Context

有关Lifting State Up

的更多信息

答案 1 :(得分:0)

据我所知,您正在对每个奇异的Movie元素执行此操作。因为每次您将相同的localStorage Item设置为单个电影的新值(作为给定Movie组件的状态仅保留一个实例的值)。最好将状态管理保留在Movie组件之外,例如在MovieS中,并且仅在Movie中进行演示工作

import React from 'react';

export default class MovieS extends React.Component{
    constructor(props){
      super(props)
      this.state = (localStorage.appState) ? JSON.parse(localStorage.appState)
      : { 0: false, 1: false, 2: false, 3: false, 4: false, 5: false};
    }

    clickedTitle = (event) => {
      if (event.target.tagName === "SPAN") {
      this.setState({
          [event.target.id]: !this.state[event.target.id]}, () => {localStorage.setItem('appState', JSON.stringify(this.state))
      });
          // localStorage.clear()

      }
    }

    render(){
        this.props.movies.map( (movie) => (

            <Movie 
            click={clickedTitle}
            className={this.state[movie.id] ? "clicked" : "not-clicked"}
            title={movie.title}
            />

        ))

    }

}

function Movie({ click, className, title }) => (
  <div className="sw_title"  onClick={click}>
    <span id={this.props.index} className={}> {} </span>
  </div>
)