update react prevstate did component javascript reactjs ecmascript-6

javascript - react - setstate component did update



setState() dentro de componentDidUpdate() (5)

Diría que debe verificar si el estado ya tiene el mismo valor que está tratando de establecer. Si es lo mismo, no tiene sentido volver a establecer el estado para el mismo valor.

Asegúrese de configurar su estado así:

let top = newValue /*true or false*/ if(top !== this.state.top){ this.setState({top}); }

Estoy escribiendo un script que mueve el menú desplegable debajo o arriba de la entrada, dependiendo de la altura del menú desplegable y la posición de la entrada en la pantalla. También quiero configurar el modificador en el menú desplegable de acuerdo con su dirección. Pero el uso de setState dentro del componentDidUpdate crea un bucle infinito (lo cual es obvio)

He encontrado una solución al usar getDOMNode y al configurar classname en el menú desplegable directamente, pero getDOMNode que debería haber una mejor solución usando las herramientas React. Alguien puede ayudarme?

Aquí hay una parte del código de trabajo con getDOMNode (una lógica de posicionamiento un poco descuidada para simplificar el código)

let SearchDropdown = React.createClass({ componentDidUpdate(params) { let el = this.getDOMNode(); el.classList.remove(''dropDown-top''); if(needToMoveOnTop(el)) { el.top = newTopValue; el.right = newRightValue; el.classList.add(''dropDown-top''); } }, render() { let dataFeed = this.props.dataFeed; return ( <DropDown > {dataFeed.map((data, i) => { return (<DropDownRow key={response.symbol} data={data}/>); })} </DropDown> ); } });

y aquí hay código con setstate (que crea un bucle infinito)

let SearchDropdown = React.createClass({ getInitialState() { return { top: false }; }, componentDidUpdate(params) { let el = this.getDOMNode(); if (this.state.top) { this.setState({top: false}); } if(needToMoveOnTop(el)) { el.top = newTopValue; el.right = newRightValue; if (!this.state.top) { this.setState({top: true}); } } }, render() { let dataFeed = this.props.dataFeed; let class = cx({''dropDown-top'' : this.state.top}); return ( <DropDown className={class} > {dataFeed.map((data, i) => { return (<DropDownRow key={response.symbol} data={data}/>); })} </DropDown> ); } });


La firma componentDidUpdate es void::componentDidUpdate(previousProps, previousState) . Con esto podrás probar qué accesorios / estado están sucios y llamar a setState consecuencia.

Ejemplo:

componentDidUpdate(previousProps, previousState) { if (previousProps.data !== this.props.data) { this.setState({/*....*/}) } }


Puede usar setState dentro de componentDidUpdate . El problema es que de alguna manera estás creando un bucle infinito porque no hay condición de interrupción.

Según el hecho de que necesita valores proporcionados por el navegador una vez que se representa el componente, creo que su enfoque sobre el uso de componentDidUpdate es correcto, solo necesita un mejor manejo de la condición que desencadena el setState .


Si usa setState dentro de componentDidUpdate , actualiza el componente, lo que resulta en una llamada a componentDidUpdate que posteriormente llama a setState nuevamente y da como resultado el bucle infinito. Debería llamar condicionalmente a setState y asegurarse de que la condición que viola la llamada ocurra eventualmente, por ejemplo:

componentDidUpdate: function() { if (condition) { this.setState({..}) } else { //do something else } }

En caso de que solo esté actualizando el componente enviándole accesorios (no lo está actualizando setState, a excepción del caso dentro de componentDidUpdate), puede llamar a setState dentro de componentWillReceiveProps lugar de componentDidUpdate .


Tuve un problema similar en el que tengo que centrar la información sobre herramientas. React setState en componentDidUpdate me puso en bucle infinito, traté de que funcionara. Pero descubrí que usar la devolución de llamada de referencia me dio una solución más simple y limpia, si usa la función en línea para la devolución de llamada de referencia, se enfrentará al problema nulo para cada actualización de componentes. Por lo tanto, use la referencia de función en la devolución de llamada de referencia y establezca el estado allí, que iniciará el renderizado