【问题标题】:How to prevent state change in React after page refresh/view change?页面刷新/视图更改后如何防止 React 中的状态更改?
【发布时间】:2019-06-06 08:06:02
【问题描述】:

我的 onClick 事件处理程序向数据库字段添加/删除 id,并根据切换状态 true/false 更改按钮颜色。 虽然数据更新工作正常,但颜色状态会在页面刷新/视图更改时重置。 我想状态需要通过回调函数传递(在这种情况下,关系是子到父),但我不确定。

我认为有必要在 LocalStorage 中“保留”当前状态,但这并没有解决问题。虽然 LocalStorage 值 'true' 和 'false' 保持其状态(如控制台中显示的那样),但刷新页面时按钮的颜色仍会重置。

我附上了可能对评估问题很重要的代码部分:

// initialization of toggle state
let toggleClick = false;

...

 this.state = {
      fav: props.favorite
    };
    this.toggleClass = this.toggleClass.bind(this);
  }

...

componentDidUpdate(prevProps) {
    if (this.props.favorite !== prevProps.favorite) {
      this.setState({
        fav: this.props.favorite
      });
    }
  }

  toggleClass() {
    toggleClick = true;
    if (!this.state.fav) {
      this.addId(this.props.movie._id);
    } else {
      this.removeId();
    }
  }

...

<span
  onClick={() => this.toggleClass()}
  className={this.state.fav ? "favme active" : "favme"}
>&#x2605;</span>

【问题讨论】:

  • 与您的问题无关,您无需再使用constructorthis.statebind(this)。你可以像state一样使用你的状态,并使用箭头函数,例如toggleClass = () =&gt; {...}而不是toggleClass(){...},因为它消除了bind(this)的必要性。使用 react 钩子,您甚至可以使用 useState() 将整个组件从类转换为函数式组件,这允许您在函数式组件中使用 state

标签: reactjs local-storage refresh setstate


【解决方案1】:

我的 React 应用程序也遇到了同样的问题。为此,我总是使用componentDidMount,因为它在渲染之后被调用。但是,如果您调用setState 函数,它会自动调用渲染,因此您的更改会出现。如果页面被刷新,状态将被重置为默认值。因此,实现这一目标的最佳方法是:

componentDidMount() {
   const getDbAnswer = //fetch a signal from the db
   if (getDBAnswer === true) {
     this.setState({ fav: true })
   else
     this.setState({ fav: false })
}

您甚至可以使用 localStorage 设置变量。请记住,localStorage 仅接受 string 值,不接受 boolean

componentDidMount() {
  const getDbAnswer = //fetch a signal from the db
  if (getDBAnswer === true)
    localStorage.setItem("fav", "true");
  else
    localStorage.setItem("fav", "false");
}

然后你可以像这样使用它:

<div className={localStorage.getItem("fav") === "true" ? "favme active" : "favme"}>

【讨论】:

  • componentWillMount 重命名为 UNSAFE_componentWillMount已弃用,并将在 React 17 中删除
  • 您可以为此目的使用构造函数而不是 componentWillMount,并且在构造函数中,您不需要 setState 只需将更新状态成员/变量。
  • @Rallen 我确实听说过这个,但并不认为它如此重要。我修改了我的答案,因为componentDidMount 更安全
【解决方案2】:

我在刷新视图时遇到了类似的问题。这是因为组件在补液完成之前渲染。我通过使用 Redux Persist 解决了我的问题。我们可以使用 Redux Persist 来延迟渲染,我将 persistStore 放在我的主组件中:

componentWillMount() {
  persistStore(store, {}, () => {
  this.setState({rehydrated: true})
  })
}

这将确保组件在 store 重新水化时重新渲染。

https://github.com/rt2zz/redux-persist

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    • 1970-01-01
    • 1970-01-01
    • 2011-08-18
    • 2017-03-06
    相关资源
    最近更新 更多