Старый компонент сохраняет состояние на кнопке возврата
У меня есть ссылка в модале, которая ведет на новую страницу, и я не могу сбросить состояние компонента с модалом при переходе на эту страницу.
Компонент с модальным режимом, похоже, сохраняет свое состояние после перехода на новую страницу, потому что, когда я нажимаю кнопку "Назад", он автоматически открывает модальный режим.
Модал открывается или закрывается в зависимости от состояния 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
Я уверен, что мне нужно исправить это с помощью componentWillUnmount
установить состояние modalIsOpen
в false перед размонтированием компонента, но, кажется, никогда не завершается установка состояния перед размонтированием.
Я использую реакцию на рельсы, которая, кажется, использует какую-то гибридную систему маршрутизации рельсы / реакции, но я не слишком знаком с ней и не хочу идти вниз по этой кроличьей норе, если я этого не сделаю должен.
Таким образом, мой вопрос, если это ожидаемое поведение жизненного цикла реагирующего компонента, есть ли способ, которым я могу обеспечить состояние modalIsOpen
сбрасывается перед размонтированием? Или есть способ, которым я могу убедиться, что мое состояние сбрасывается в исходное состояние при возвращении? Или это скорее следствие системы маршрутизации, которую я использую?
1 ответ
Это странное, неожиданное поведение в реакции и, конечно, не вызвано реакцией (как говорилось в @azium), а некоторыми "вещами вокруг", возможно, проблемой response_on_rails (или "функцией"). Сообщить об ошибке / создать проблему на github.
Как вы видите в журнале состояние имеет правильное значение при монтировании, и нет причин для визуализации модальных. "Нормальная" реакция будет работать как положено.
Нет смысла устанавливать состояние на unmount - экземпляр компонента будет уничтожен, его состояние тоже.
HINTS
Вы не должны хранить модальный контент в состоянии. Это возможно, это работает для простых случаев, это может быть своего рода кеш для частей контента, но у вас могут быть проблемы, когда требуется условное повторное рендеринг (с использованием изменений проп / состояния).
После установки состояния this.setState({modalIsOpen: true, modalContent:listing})
в обработчике кликов вы можете использовать условный рендеринг (в рендере):
{this.state.modalIsOpen && <ListingModalContent listing={this.state.modalContent}/>}
Чтобы быть правдой даже this.setState({modalIsOpen: true})
может быть удален (сохраняя только перечисление idx в состоянии, '-1' для закрытия), но тогда код может быть менее читабельным (хранение дополнительного указателя обходится дешево).