update read react property not modify force example componentdidmount cannot javascript reactjs

javascript - read - states en react



React setState solo puede actualizar un componente montado o de montaje (4)

Estoy recibiendo la siguiente advertencia

"Advertencia: setState (...): solo se puede actualizar un componente montado o de montaje. Esto generalmente significa que llamó a setState () en un componente sin montar. Esto no es una opción. Verifique el código del componente ContactPage".

Cuando inicialmente voy a la página de contacto, la primera vez está bien. Luego, si navego fuera de la página y vuelvo atrás, se lanza la advertencia.

Componente de la página de contacto:

import React, { Component, PropTypes } from ''react''; import AppStore from ''../../stores/AppStore''; import AppActions from ''../../actions/AppActions''; import DataContent from ''./DataContent''; const title = ''Contact Us''; class ContactPage extends Component { constructor(props) { super(props); this.state = AppStore.getState(); AppActions.getData(); } static contextTypes = { onSetTitle: PropTypes.func.isRequired, }; componentWillMount() { this.context.onSetTitle(title); AppStore.listen(this.onChange.bind(this)); } componentWillUnmount() { AppStore.unlisten(this.onChange.bind(this)); } onChange(state) { this.setState(state); } renderData() { return this.state.data.map((data) => { return ( <DataContent key={data.id} data={data} /> ) }) } render() { return ( <div className={s.root}> <div className={s.container}> <h1>{title}</h1> <div> { this.renderData() } </div> </div> </div> ); } } export default ContactPage;

Cuando instalo a los depuradores, en la carga de la página de contacto se encuentra con componentWillMount (). Cuando salgo de la página de contacto, llega a componentWillUnmount (). Cuando vuelvo a la página, vuelve a golpear componentWillMount () y luego lanza el error cuando llega a la función onChange (estado).


Antes del cambio, se monta el componente de comprobación de estado.

render() { return ( <div ref="root" className={s.root}> // ---- </div> )}; onChange(state) { if(this.refs.root) { this.setState(state); } }

Creo que esto te ayudará.


El problema es que el oyente de la instancia del componente anterior todavía está registrado. Y debido a que la instancia anterior ya no está montada, obtienes ese error.

.bind siempre devuelve una nueva función. Así que si lo haces

AppStore.unlisten(this.onChange.bind(this));

entonces está intentando eliminar un oyente que no existe (lo que, por supuesto, falla). No elimina la escucha que se registró con AppStore.listen(this.onChange.bind(this))

Para resolver esto, debe enlazar el controlador una vez en el constructor:

this.onChange = this.onChange.bind(this);

y luego use AppStore.listen(this.onChange) y AppStore.unlisten(this.onChange) .


En su caso, agregue una referencia a su div raíz y verifique el valor de referencia antes de llamar a setState.

Tu método onChange debería onChange así:

onChange(state) { this.refs.yourRef ? this.setState(state) : null; }


Yo también estaba luchando con este problema durante bastante tiempo.

Lo que resolví para mí fue hacer lo que propuso @Felix Kling, pero también asegurarme de que mi función de devolución de llamada fuera declarada dentro de la clase del componente, de lo contrario, no podrá usar this prefijo, que aparentemente fue lo que me sirvió.

Aquí hay un ejemplo de lo que quiero decir:

Legal, pero no funciona

function onChange() { this.setState({ MyState: newState }) } class MyComponent extends React.Component { constructor(props) { super(props); onChange = onChange.bind(this); } componentDidMount() { window.addEventListener(''resize'', onChange); } componentWillUnmount() { window.removeEventListener(''resize'', onChange); } render() { ... } }

Trabajos

class MyComponent extends React.Component { constructor(props) { super(props); this.onChange = this.onChange.bind(this); } onChange() { this.setState({ MyState: newState }) } componentDidMount() { window.addEventListener(''resize'', this.onChange); } componentWillUnmount() { window.removeEventListener(''resize'', this.onChange); } render() { ... } }

Espero que ayude a alguien más a enfrentar este problema. :)