【问题标题】:Old component retains state on back button旧组件在后退按钮上保留状态
【发布时间】:2018-09-01 20:53:17
【问题描述】:

我在模态框中有一个指向新页面的链接,但在指向该页面时,我似乎无法使用模态框重置组件的状态。

带有模态的组件在指向新页面后似乎保持其状态,因为当我点击后退按钮时,它会自动打开模态。

模态框根据modalIsOpen的状态打开或关闭。

所以我有我简化的Listings 组件:

import React from 'react'
import ListingModalContent from '../ListingModalContent'
import Modal from '../Modal'

export default class Listings extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      modalIsOpen: false,
      modalContent: null
    }
  }

  modalClick = (e, listing) => {
    e.preventDefault()
    this.setState({
      modalContent: <ListingModalContent listing={listing}/>
    }, () => {
      this.setState({modalIsOpen: true})
    })
  }

  modalClose = () => {
    this.setState({modalIsOpen: false})
  }

  componentWillMount() {
    this.setState({modalIsOpen: false})
    console.log('mounting...')
    console.log(this.state.modalIsOpen)
  }

  componentWillUnmount() {
    console.log('unmounting...')

    this.setState({
      modalIsOpen: false
    }, () => {
      console.log('got here...')
      console.log(this.state.modalIsOpen)
    })

    console.log(this.state.modalIsOpen)
  }

  render() {

    const listings = this.props.listings.map(listing => (<div className="listing">
      <a href="#" onClick={e => this.modalClick(e, listing)}>More Details</a>
    </div>))

    return (<div id="listings">
      <section className="listings">
        {listings}
        <Modal visible={this.state.modalIsOpen} onClose={this.modalClose}>
          {this.state.modalContent}
        </Modal>
      </section>
    </div>)
  }
}

还有我的ListingsModalContent 组件:

import React from 'react'

export default class ListingModalContent extends React.Component {
  constructor(props) {
    super(props)
  }

  render() {

    const {listing} = this.props

    return (<div className="listing-modal">
      <div className="details">
        <h2 className="address">{listing.address}</h2>
        <p className="description">{listing.description}</p>
      </div>
      <div className="btn-container">
        <a href={`/listings/${listing.slug}`} onClick={this.props.modalClose}>View Full Listing</a>
      </div>
    </div>)
  }
}

控制台输出是...

// after initially mounting:
mounting...
false

// after clicking the listing link:
unmounting...
true

// after hitting the back button:
mounting...
false

我很确定我需要在卸载组件之前使用 componentWillUnmountmodalIsOpen 的状态设置为 false 来解决此问题,但它似乎永远不会在卸载之前完成设置状态。

我正在使用react on rails,它似乎使用了一些混合路由 rails/react 路由系统,但我对它不太熟悉,如果我现在不想进入那个兔子洞不必。

所以我的问题是,如果这是反应组件生命周期的预期行为,有没有办法可以确保在卸载之前重置 modalIsOpen 的状态?或者有什么方法可以确保我的状态在返回时重置为初始状态?还是这更可能是我使用的路由系统的结果?

【问题讨论】:

  • 您的意思是当您点击带有文字View Full Listing 的链接时? `/listings/${listing.slug}}` 部分?你确定你没有收到错误吗? this.close 没有在那里定义
  • 这只是我在将其发布到 stackoverflow 之前尝试的最后一次尝试,尝试在单击链接时将 modalIsOpen 设置为 false。由于我对组件所做的所有编辑和简化,我把它搞砸了。我在问题中修复了它以反映我实际尝试做的事情。但我认为这也不是解决方案。
  • 点击带有有效href&lt;a&gt; 标记(即不是#)将触发浏览器的硬刷新,并且无法保持任何状态。只有在这种逻辑存在的情况下才能对其进行补水。不需要onClick 处理程序,因为浏览器将导航离开,老派,不使用history.push。这很容易测试。在浏览器控制台输入let x = 10,点击一个有效的a标签(加载一个新页面)并检查x仍然是10。如果它不是(它不应该是)并且您的状态以某种方式持续存在,那么您必须将状态存储在其他地方,例如 localstorage 或服务器上并重新补水。

标签: ruby-on-rails reactjs routing state react-on-rails


【解决方案1】:

这是 react 中奇怪的、意想不到的行为,而且肯定不是由 react 引起的(如 @azium 所述),而是一些“周围的东西”,可能是 react_on_rails 问题(或“功能”)。 在 github 上报告错误/创建问题。

正如您在日志状态中看到的那样,在挂载时具有适当的价值,并且没有理由呈现模态。 “正常”反应会按预期工作。

在卸载时设置状态是没有意义的 - 组件实例及其状态也会被销毁。

提示

您不应该在状态中存储模态内容。有可能,它适用于简单的情况,它可以用作部分内容的缓存,但 您可能会遇到问题需要条件重新渲染时(使用道具/状态更改)。

在点击处理程序中设置状态this.setState({modalIsOpen: true, modalContent:listing}) 后,您可以使用条件渲染(在渲染中):

{this.state.modalIsOpen && <ListingModalContent listing={this.state.modalContent}/>}

确实,即使 this.setState({modalIsOpen: true}) 也可以删除(通过仅保存状态中的列表 idx,'-1' 用于关闭),但代码的可读性可能会降低(存储额外的指针很便宜)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 2020-07-04
    相关资源
    最近更新 更多