旧组件保留后退按钮上的状态

时间:2018-09-01 20:53:18

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

我在模态中有一个链接,该链接可以转到新页面,并且在定向到该页面时,我似乎无法使用模态重置组件的状态。

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

根据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来解决此问题,但是组件卸载之前似乎永远不会完成设置状态。 / p>

我正在使用react on rails,它似乎使用了一些混合布线导轨/反应式布线系统,但是我不太熟悉它,并且现在不想掉进那个兔子洞中如果不需要的话。

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

1 个答案:

答案 0 :(得分:0)

这是奇怪的,意外的反应行为,并且肯定不是由反应引起的(如@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'),但是代码的可读性却较低(存储额外的指针很便宜)。