javascript - mapstatetoprops - Saber cuándo está lista la interfaz de usuario en React/Redux
redux react native (6)
Dos pasos para lograrlo.
Seguimiento de todas las solicitudes HTTP a través de acciones
Un simple contador en estado de redux sería suficiente, que aumenta en el inicio de la solicitud y disminuye en éxito o falla (todo a través de acciones apropiadas). window.dirty.stuff
no window.dirty.stuff
ninguna window.dirty.stuff
. window.dirty.stuff
en frente de Dan Abramov.
Rastrear todos los componentes connect
componentDidUpdate
método componentDidUpdate
indica que todos los hijos terminaron de renderizar. Esto se puede lograr sin una gran cantidad de repeticiones con el lifecycle
recompra HOC. El lugar correcto para comenzar a rastrear la re-renderización podría ser el método sCU
o simplemente cWRP
si usa recompose
s shouldUpdate
o reselect
ya, ya que no rastrearemos los componentes que no se actualizaron.
Tenga en cuenta que todo está suponiendo una aplicación de reacción / reduxomomática, sin efectos secundarios o animaciones complicados. Por ejemplo, si algún componente secundario en algún lugar de la jerarquía dispara su propia solicitud AJAX, digamos en el cDM
, no a través de una acción de redux. De esta manera usted también tiene que rastrearlos, PERO nadie puede estar seguro si implican re-renders. Rastrear tales comportamientos todavía es posible, solo podría requerir más esfuerzo.
Me gustaría saber cuánto tiempo tarda mi aplicación en estar "lista" para que el usuario interactúe con ella. La línea de tiempo de la carga de la aplicación incluye lo siguiente:
- Carga del DOM
- Reactivo inicial de render.
- Llamadas HTTP activadas desde varios
componentDidMount()
s - Retorno de llamadas HTTP. El estado redux se actualiza con respuestas HTTP.
- React procesa con nuevos valores de las respuestas HTTP.
- Toda la carga inicial está completa. El usuario está listo para interactuar con la aplicación.
Al final de este proceso, me gustaría window.performance.now()
un evento de seguimiento para registrar el valor de window.performance.now()
.
No estoy seguro de cuál es la mejor manera de hacer esto. El sistema de componentes de React hace un buen trabajo al desacoplar varias partes de la interfaz de usuario. En este caso, desafortunadamente, significa que no voy a tener un lugar fácil de verificar para saber "todo se ha procesado con los nuevos datos".
Cosas que he probado o considerado:
- Busque un enlace de ciclo de vida React que me diga si algún niño se está actualizando. Algo como
componentOrAnyChildDidUpdate()
. No creo que esto exista, y puede ser contrario a la filosofía React. -
anyChildDidUpdate()
unanyChildDidUpdate()
ciclo de vidaanyChildDidUpdate()
través delcontext
y haga de cada componente de mi aplicación una subclase como una clase base abstracta auxiliar o sea envuelto en un componente de orden superior. Esto parece malo porque elcontext
es una API experimental . - Suscríbase al estado Redux a través de
store.subscribe()
. Actualice el estado de Redux para tener un registro explícito de si se han devuelto todas las llamadas HTTP. Una vez que todas las llamadas HTTP han regresado, y React termina de volver a renderizarse, entonces sé que hay que activar la devolución de llamada de seguimiento. El problema es saber cuándo React ha terminado de volver a renderizar. Funcionaría si en mistore.subscribe()
se garantizara que la devolución de llamada se ejecutaría sincrónicamente despuésreact-redux
la devolución de llamada dereact-redux
. Pero ese no es el caso.
¿Hay una buena manera de hacer esto en React?
En nuestro proyecto, usamos redux y un par de acciones: disparador, solicitud, éxito, error.
"Activar" llama a la solicitud y lanza la carga: verdadero en nuestro "inteligente" componente "Solicitud", busca los datos y los arroja al "Éxito" Error / Error, nos dice que todo está bien y que los datos están cargados y lanzados {loading: false, data}
En caso de éxito / error, siempre sabemos que está sucediendo con nuestra aplicación.
Y, por supuesto, puede usar componentWillReceiveProps (nextProps) {} y verificar el indicador de carga y los datos en su componente
Hay más de una forma de hacer lo que me estás pidiendo, pero desde el principio, haría lo siguiente:
• Cree un reductor de performance.now()
y llame a performance.now()
justo antes de realizar el almacenamiento de redux y añada el valor al estado inicial.
{ perf: { start: ''...'', end: ''...'' } }
• Seguimiento del estado de carga de las solicitudes HTTP iniciales en un reductor cargado.
{ loaded: { request1: false, request2: false, request3: false } }
• Conecte el componente de nivel superior al reductor cargado y verifique si todas las solicitudes están completas en componentDidUpdate. Si es verdadero, agregue el valor final al reductor perf.
import React from ''react'';
import { connect } from ''react-redux'';
class App extends React.Component {
componentDidUpdate(prevProps) {
if (!prevProps.loadingComplete && this.props.loadingComplete) {
this.props.updatePerf(performance.now());
}
}
}
const mapStateToProps = state => ({
loadingComplete: state.loaded.every(item => item),
});
const mapDispatchToProps = dispatch => ({
updatePerf(time) {
dispatch({ type: ''SET_ENDING_PERF'', payload: time });
},
});
export default connect(mapStateToProps, mapDispatchToProps)(App);
Me temo que no hay una manera universalmente buena de hacer esto en React, esta es la "lógica" que está relacionada con la estructura de su aplicación.
Quería mostrar un cargador al navegar de una página a otra en la Aplicación de página única (SPA) escrita en Reactive y tuve un problema similar al no saber cuándo dejar de mostrarlo y si todos los componentes de la nueva página han completado sus llamadas a la API / rinde.
La forma en que lo resolví fue:
1) Eliminé todas mis llamadas API desde dentro de mis componentes.
2) Cree un componente de Página para envolver todos los componentes incluidos en esa página (invocado por su enrutador de reacción).
3) Realice todas las solicitudes requeridas para sus componentes simultáneamente en la navegación (en mi caso, mientras se muestra el cargador). Para cada solicitud que complete, cree una promesa y dentro de ella cree su componente dinámicamente usando React.createElement. Pase al componente creado la respuesta de solicitud y el controlador de promesa como props.
4) Resuelva la promesa en el componenteDidMount de su componentDidMount
.
5) Una vez que se hayan resuelto todas las promesas, sabrá que la "página" está lista y puede registrar el valor de window.performance.now()
.
Es difícil proporcionar un ejemplo de código mínimo sin mucho código fuera de contexto, ya que este código se distribuye por toda la aplicación.
Puedes intentar usar react-addons-perf
Así es como comparto mis aplicaciones por lo general:
Básicamente, desea comenzar a medir cuando su componente comience a actualizarse y detener la medición después del método de ciclo de vida componentDidUpdate()
.
import Perf from ''react-addons-perf''
componentWillMount() {
window.performance.mark(''My app'');
}
componentDidMount() {
console.log(window.performance.now(''My app''));
Perf.start()
// ... do your HTTP requests
}
componentDidUpdate() {
Perf.stop();
Perf.printInclusive();
}
Al igual que usted hará un seguimiento de su componente de procesamiento inicial + sus actualizaciones de componentes.
Espero eso ayude
a partir de un punto de vista de diseño, en mi opinión, estar listo o no es una propiedad de presentación del usuario y, por lo tanto, debe ser manejado solo por componentes de reacción.
por ejemplo, más tarde puede decidir permitir que el usuario interactúe con alguna parte de su interfaz de usuario mientras otras partes aún se están cargando, o puede decidir que algunos componentes deberían permitir que el usuario interactúe antes de que el modelo de datos esté listo, etc. en otras palabras, es un componente (reactivo) la responsabilidad de saber si / cuándo está listo o no y nadie más.
Es decir, todos los componentes ''waitable'' podrían exponer un soporte similar a una carga que se pasará por el árbol de reacción; el componente raíz luego coordinaría el resultado cambiando el árbol hacia abajo en consecuencia, propagando los apoyos apropiados hacia las hojas.
Esto podría implementarse escribiendo un componente mixin / high order para encapsular la lógica de "actualización de preparación".