react que pasar entre datos comunicacion componentes componentdidmount reactjs redux react-redux

reactjs - que - react js



¿Cómo sabe un componente conectado redux cuándo volver a renderizar? (4)

Probablemente me estoy perdiendo algo muy obvio y me gustaría aclararme.

Aquí está mi entendimiento.
En un componente de reacción ingenua, tenemos states y props . El state actualización con setState vuelve a representar todo el componente. props son principalmente de solo lectura y actualizarlos no tiene sentido.

En un componente de reacción que se suscribe a una tienda redux, a través de algo como store.subscribe(render) , obviamente se vuelve a renderizar cada vez que se actualiza la tienda.

react-redux tiene una connect() auxiliar connect() que inyecta parte del árbol de estado (que es de interés para el componente) y actionCreators como props para el componente, generalmente a través de algo como

const TodoListComponent = connect( mapStateToProps, mapDispatchToProps )(TodoList)

Pero con el entendimiento de que un setState es esencial para que TodoListComponent reaccione al cambio de árbol de estado redux (re-render), no puedo encontrar ningún state o código relacionado con setState en el archivo del componente TodoList . Se lee algo como esto:

const TodoList = ({ todos, onTodoClick }) => ( <ul> {todos.map(todo => <Todo key={todo.id} {...todo} onClick={() => onTodoClick(todo.id)} /> )} </ul> )

¿Puede alguien señalarme en la dirección correcta lo que me estoy perdiendo?

PD: estoy siguiendo el ejemplo de la lista de tareas incluidas con el https://github.com/reactjs/redux/tree/master/examples/todos/src/containers .


Como sé que solo lo que hace Redux, al cambiar el estado de la tienda, se llama a componentWillRecieveProps si su componente dependía del estado mutado y luego debe forzar a su componente a actualizarlo.

1-store State change-2-call (componentWillRecieveProps (() => {cambio de estado de 3 componentes}))


Esta respuesta es un resumen del artículo de Brian Vaughn titulado here (07 de junio de 2018).

Derivar el estado de los accesorios es un antipatrón en todas sus formas. Incluyendo el uso del componentWillReceiveProps anteriorWillReceiveProps y el nuevo getDerivedStateFromProps .

En lugar de derivar el estado de los accesorios, considere las siguientes soluciones.

Dos recomendaciones de mejores prácticas.

Recomendación 1. Componente totalmente controlado

function EmailInput(props) { return <input onChange={props.onChange} value={props.email} />; } Recomendación 2. Componente totalmente incontrolado con una llave

// parent class class EmailInput extends Component { state = { email: this.props.defaultEmail }; handleChange = event => { this.setState({ email: event.target.value }); }; render() { return <input onChange={this.handleChange} value={this.state.email} />; } } // child instance <EmailInput defaultEmail={this.props.user.email} key={this.props.user.id} />

Dos alternativas si, por alguna razón, las recomendaciones no funcionan para su situación.

Alternativa 1: restablecer el componente no controlado con un accesorio de identificación

class EmailInput extends Component { state = { email: this.props.defaultEmail, prevPropsUserID: this.props.userID }; static getDerivedStateFromProps(props, state) { // Any time the current user changes, // Reset any parts of state that are tied to that user. // In this simple example, that''s just the email. if (props.userID !== state.prevPropsUserID) { return { prevPropsUserID: props.userID, email: props.defaultEmail }; } return null; } // ... } Alternativa 2: restablecer componente no controlado con un método de instancia

class EmailInput extends Component { state = { email: this.props.defaultEmail }; resetEmailForNewUser(newEmail) { this.setState({ email: newEmail }); } // ... }


La función de connect genera un componente contenedor que se suscribe a la tienda. Cuando se despacha una acción, se notifica la devolución de llamada del componente contenedor. Luego ejecuta su función mapState y compara superficialmente el objeto de resultado de este momento con el objeto de resultado de la última vez (por lo tanto, si reescribiera un campo de almacenamiento redux con su mismo valor, no se activaría una nueva representación). Si los resultados son diferentes, los pasa a su componente "real" como accesorios.

Dan Abramov escribió una excelente versión simplificada de connect en ( https://gist.github.com/gaearon/1d19088790e70ac32ea636c025ba424e ) que ilustra la idea básica, aunque no muestra nada del trabajo de optimización. También tengo enlaces a varios artículos sobre el rendimiento de Redux que discuten algunas ideas relacionadas.

actualizar

React-Redux v6.0.0 realizó algunos cambios internos importantes en la forma en que los componentes conectados reciben sus datos de la tienda.

Como parte de eso, escribí una publicación que explica cómo funcionan la API de connect y sus componentes internos, y cómo han cambiado con el tiempo:

Idiomatic Redux: la historia y la implementación de React-Redux


Mi respuesta está un poco fuera del campo izquierdo. Arroja luz sobre un problema que me llevó a esta publicación. En mi caso, parecía que la aplicación no se estaba volviendo a procesar, a pesar de que recibió nuevos accesorios.
Los desarrolladores de React tenían una respuesta a esta pregunta que a menudo se hacía con la idea de que si la (tienda) estaba mutada, el 99% de las veces esa es la razón por la que reaccionar no se volverá a procesar. Sin embargo, nada sobre el otro 1%. La mutación no fue el caso aquí.

TLDR;

componentWillReceiveProps es cómo se puede mantener el state sincronizado con los nuevos props .

Edge Case: una vez que el state actualiza, ¡la aplicación se vuelve a procesar!

Resulta que si su aplicación usa solo el state para mostrar sus elementos, los props pueden actualizarse, pero el state no lo hará, por lo que no se volverá a procesar.

Tenía un state que dependía de los props recibidos de la store redux. Los datos que necesitaba todavía no estaban en la tienda, así que los obtuve de componentDidMount , como es apropiado. Me devolvieron los accesorios, cuando mi reductor actualizó la tienda, porque mi componente está conectado a través de mapStateToProps. Pero la página no se procesó y el estado aún estaba lleno de cadenas vacías.

Un ejemplo de esto es decir que un usuario cargó una página "editar publicación" desde una URL guardada. Tiene acceso al postId desde la URL, pero la información aún no está store , por lo que debe buscarla. Los elementos de su página son componentes controlados, por lo que todos los datos que está mostrando están en state .

Usando redux, se obtuvieron los datos, se actualizó la tienda y se connect el componente, pero la aplicación no reflejó los cambios. En una mirada más cercana, se recibieron props , pero la aplicación no se actualizó. state no se actualizó.

Bueno, los props se actualizarán y propagarán, pero el state no. Debe indicarle específicamente al state que actualice.

No puede hacer esto en render() , y componentDidMount ya terminó sus ciclos.

componentWillReceiveProps es donde actualiza state propiedades de state que dependen de un valor de prop modificado.

Ejemplo de uso:

componentWillReceiveProps(nextProps){ if (this.props.post.category !== nextProps.post.category){ this.setState({ title: nextProps.post.title, body: nextProps.post.body, category: nextProps.post.category, }) } }

Debo dar un agradecimiento a este artículo que me iluminó sobre la solución que docenas de otras publicaciones, blogs y repositorios no mencionaron. Cualquier otra persona que haya tenido problemas para encontrar una respuesta a este problema evidentemente oscuro, aquí está:

Métodos del ciclo de vida del componente ReactJs: una inmersión profunda

componentWillReceiveProps es donde actualizará el state para mantenerse sincronizado con las actualizaciones de los props .

Una vez que el state actualiza, ¡los campos que dependen del state vuelven a procesar!