Estoy escribiendo un script que mueve el menú desplegable por debajo o por encima 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 usar setState
dentro de la componentDidUpdate
crea un bucle infinito (que es obvio)
He encontrado una solución al usar getDOMNode
y configurar classname para desplegable directamente, pero creo 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>
);
}
});
fuente
setState
habrá siempre desencadenar una re-render. En lugar de verificarstate.top
y llamarsetState
varias veces, solo haga un seguimiento de lo que deseastate.top
que esté en una variable local, luego una vez al final de lacomponentDidUpdate
llamadasetState
solo si su variable local no coincidestate.top
. Tal como está ahora, reinicia inmediatamentestate.top
después del primer renderizado, lo que lo coloca en el ciclo infinito.componentDidUpdate
en este violín .componentShouldUpdate
?Respuestas:
Puedes usar
setState
dentrocomponentDidUpdate
. El problema es que de alguna manera estás creando un ciclo infinito porque no hay condición de ruptura.Según el hecho de que necesita valores proporcionados por el navegador una vez que se procesa el componente, creo que su enfoque sobre el uso
componentDidUpdate
es correcto, solo necesita un mejor manejo de la condición que desencadena elsetState
.fuente
componentDidUpdate
y solo se puede agregar según sea necesariorender
.La
componentDidUpdate
firma esvoid::componentDidUpdate(previousProps, previousState)
. Con esto podrás probar qué accesorios / estado están sucios y llamar ensetState
consecuencia.Ejemplo:
fuente
componentDidMount
no tiene ningún argumento, y solo se llama cuando se crea el componente, por lo que no se puede usar para el propósito descrito.componentDidMount
, así que cuando escribí la respuesta el famoso nombre cayó en cascada 😮 Nuevamente, ¡Gracias y genial ponerse al día!componentDidUpdate(prevProps, prevState) { if ( prevState.x!== this.state.x) { //Do Something } }
Si lo usa
setState
dentrocomponentDidUpdate
, actualiza el componente, lo que resulta en una llamada a lacomponentDidUpdate
que posteriormentesetState
vuelve a llamar, lo que resulta en un bucle infinito. Debe llamar condicionalmentesetState
y asegurarse de que la condición que viola la llamada ocurra eventualmente, por ejemplo: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
inside encomponentWillReceiveProps
lugar decomponentDidUpdate
.fuente
getDerivedStateFromProps
.Este ejemplo lo ayudará a comprender los ganchos del ciclo de vida de React .
Puede
setState
engetDerivedStateFromProps
el método es decir,static
y desencadenar el método después de apoyos cambian encomponentDidUpdate
.En
componentDidUpdate
obtendrá 3er parámetro que regresa degetSnapshotBeforeUpdate
.Puedes consultar este enlace de códigos y casillas
fuente
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í:
fuente
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
fuente