Estoy tratando de entender el método de conexión de react-redux y las funciones que toma como parámetros. En particular mapStateToProps()
.
Según tengo entendido, el valor de retorno de mapStateToProps
será un objeto derivado del estado (ya que vive en la tienda), cuyas claves se pasarán a su componente de destino (se aplica el componente de conexión) como accesorios.
Esto significa que el estado consumido por su componente objetivo puede tener una estructura muy diferente del estado almacenado en su tienda.
P: ¿Está bien?
P: ¿Es esto esperado?
P: ¿Es esto un anti-patrón?
Q: Is this ok?
A: si
P: Is this expected?
Sí, se espera esto (si está utilizando react-redux).
P: Is this an anti-pattern?
R: No, esto no es un anti-patrón.
Se llama "conectar" su componente o "hacerlo inteligente". Es por diseño.
Le permite desacoplar su componente de su estado un tiempo adicional, lo que aumenta la modularidad de su código. También le permite simplificar el estado de su componente como un subconjunto del estado de su aplicación que, de hecho, le ayuda a cumplir con el patrón Redux.
Piénselo de esta manera: se supone que una tienda contiene el estado completo de su aplicación.
Para aplicaciones grandes, esto podría contener docenas de propiedades anidadas en muchas capas de profundidad.
No querrás cargar con todo eso en cada llamada (caro).
Sin mapStateToProps
o sin algún análogo del mismo, estaría tentado de dividir su estado de otra manera para mejorar el rendimiento / simplificar.
Si es correcto. Es solo una función auxiliar para tener una forma más sencilla de acceder a las propiedades de su estado
Imagina que tienes una posts
clave en tu aplicaciónstate.posts
state.posts //
/*
{
currentPostId: "",
isFetching: false,
allPosts: {}
}
*/
Y componente Posts
De forma predeterminada connect()(Posts)
, todos los accesorios de estado estarán disponibles para el componente conectado
const Posts = ({posts}) => (
<div>
{/* access posts.isFetching, access posts.allPosts */}
</div>
)
Ahora, cuando asigna el state.posts
componente a su componente, se vuelve un poco mejor
const Posts = ({isFetching, allPosts}) => (
<div>
{/* access isFetching, allPosts directly */}
</div>
)
connect(
state => state.posts
)(Posts)
mapDispatchToProps
normalmente tienes que escribir dispatch(anActionCreator())
con bindActionCreators
puedes hacerlo también más fácilmente como
connect(
state => state.posts,
dispatch => bindActionCreators({fetchPosts, deletePost}, dispatch)
)(Posts)
Ahora puedes usarlo en tu Componente
const Posts = ({isFetching, allPosts, fetchPosts, deletePost }) => (
<div>
<button onClick={() => fetchPosts()} />Fetch posts</button>
{/* access isFetching, allPosts directly */}
</div>
)
Un ejemplo de actionCreator: deletePost
const deletePostAction = (id) => ({
action: 'DELETE_POST',
payload: { id },
})
Entonces, bindActionCreators
solo tomará sus acciones, las envolverá en una dispatch
llamada. (No leí el código fuente de redux, pero la implementación podría verse así:
const bindActionCreators = (actions, dispatch) => {
return Object.keys(actions).reduce(actionsMap, actionNameInProps => {
actionsMap[actionNameInProps] = (...args) => dispatch(actions[actionNameInProps].call(null, ...args))
return actionsMap;
}, {})
}
Tienes la primera parte bien:
Yes mapStateToProps
tiene el estado Store como argumento / parámetro (proporcionado por react-redux::connect
) y se usa para vincular el componente con cierta parte del estado de la tienda.
Al vincular me refiero a que el objeto devuelto por mapStateToProps
se proporcionará en el momento de la construcción como accesorios y cualquier cambio posterior estará disponible a través de componentWillReceiveProps
.
Si conoce el patrón de diseño de Observer, es exactamente eso o una pequeña variación de él.
Un ejemplo ayudaría a aclarar las cosas:
import React, {
Component,
} from 'react-native';
class ItemsContainer extends Component {
constructor(props) {
super(props);
this.state = {
items: props.items, //provided by [email protected]
filteredItems: this.filterItems(props.items, props.filters),
};
}
componentWillReceiveProps(nextProps) {
this.setState({
filteredItems: this.filterItems(this.state.items, nextProps.filters),
});
}
filterItems = (items, filters) => { /* return filtered list */ }
render() {
return (
<View>
// display the filtered items
</View>
);
}
}
module.exports = connect(
//mapStateToProps,
(state) => ({
items: state.App.Items.List,
filters: state.App.Items.Filters,
//the State.App & state.App.Items.List/Filters are reducers used as an example.
})
// mapDispatchToProps, that's another subject
)(ItemsContainer);
Puede haber otro componente de reacción llamado itemsFilters
que maneje la pantalla y persista el estado del filtro en el estado de Redux Store, el componente de demostración está "escuchando" o "suscrito" a los filtros de estado de Redux Store, por lo que cada vez que los filtros almacenan cambios de estado (con la ayuda de filtersComponent
) reaccionar -redux detecta que hubo un cambio y notifica o "publica" todos los componentes que están escuchando / suscritos enviando los cambios a sus componentWillReceiveProps
que, en este ejemplo, activarán un nuevo filtro de los elementos y actualizarán la pantalla debido al hecho de que el estado de reacción ha cambiado .
Avíseme si el ejemplo es confuso o no es lo suficientemente claro como para proporcionar una mejor explicación.
En cuanto a: Esto significa que el estado consumido por su componente objetivo puede tener una estructura muy diferente del estado almacenado en su tienda.
No recibí la pregunta, ¡pero sé que el estado de reacción ( this.setState
) es totalmente diferente del estado de Redux Store!
El estado de reacción se usa para manejar el rediseño y el comportamiento del componente de reacción. El estado de reacción está contenido en el componente exclusivamente.
El estado de Redux Store es una combinación de estados de reductores de Redux, cada uno es responsable de administrar una pequeña parte de la lógica de la aplicación. ¡Se puede acceder a esos atributos reductores con la ayuda de react-redux::[email protected]
cualquier componente! Lo que hace que la aplicación de acceso al estado de la tienda Redux sea amplia, mientras que el estado del componente es exclusivo para sí mismo.
Este ejemplo de react & redux se basa en el ejemplo de Mohamed Mellouki. Pero valida usando reglas de embellecimiento y pelaje . Tenga en cuenta que definimos nuestros accesorios y métodos de envío utilizando PropTypes para que nuestro compilador no nos grite. Este ejemplo también incluyó algunas líneas de código que faltaban en el ejemplo de Mohamed. Para usar connect, deberá importarlo desde react-redux . Este ejemplo también vincula el método filterItems, lo que evitará problemas de alcance en el componente . Este código fuente se ha formateado automáticamente con JavaScript Prettify .
import React, { Component } from 'react-native';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
class ItemsContainer extends Component {
constructor(props) {
super(props);
const { items, filters } = props;
this.state = {
items,
filteredItems: filterItems(items, filters),
};
this.filterItems = this.filterItems.bind(this);
}
componentWillReceiveProps(nextProps) {
const { itmes } = this.state;
const { filters } = nextProps;
this.setState({ filteredItems: filterItems(items, filters) });
}
filterItems = (items, filters) => {
/* return filtered list */
};
render() {
return <View>/*display the filtered items */</View>;
}
}
/*
define dispatch methods in propTypes so that they are validated.
*/
ItemsContainer.propTypes = {
items: PropTypes.array.isRequired,
filters: PropTypes.array.isRequired,
onMyAction: PropTypes.func.isRequired,
};
/*
map state to props
*/
const mapStateToProps = state => ({
items: state.App.Items.List,
filters: state.App.Items.Filters,
});
/*
connect dispatch to props so that you can call the methods from the active props scope.
The defined method `onMyAction` can be called in the scope of the componets props.
*/
const mapDispatchToProps = dispatch => ({
onMyAction: value => {
dispatch(() => console.log(`${value}`));
},
});
/* clean way of setting up the connect. */
export default connect(mapStateToProps, mapDispatchToProps)(ItemsContainer);
Este código de ejemplo es una buena plantilla como punto de partida para su componente.
React-Redux connect
se usa para actualizar la tienda para cada acción.
import { connect } from 'react-redux';
const AppContainer = connect(
mapStateToProps,
mapDispatchToProps
)(App);
export default AppContainer;
Se explica de manera muy simple y clara en este blog .
Puede clonar el proyecto github o copiar y pegar el código de ese blog para comprender la conexión de Redux.
Aquí hay un esquema / texto estándar para describir el comportamiento de mapStateToProps
:
(Esta es una implementación muy simplificada de lo que hace un contenedor Redux).
class MyComponentContainer extends Component {
mapStateToProps(state) {
// this function is specific to this particular container
return state.foo.bar;
}
render() {
// This is how you get the current state from Redux,
// and would be identical, no mater what mapStateToProps does
const { state } = this.context.store.getState();
const props = this.mapStateToProps(state);
return <MyComponent {...this.props} {...props} />;
}
}
y después
function buildReduxContainer(ChildComponentClass, mapStateToProps) {
return class Container extends Component {
render() {
const { state } = this.context.store.getState();
const props = mapStateToProps(state);
return <ChildComponentClass {...this.props} {...props} />;
}
}
}
Es un concepto simple. Redux crea un objeto de estado ubicuo (una tienda) a partir de las acciones en los reductores. Al igual que un componente de React, este estado no tiene que codificarse explícitamente en ningún lugar, pero ayuda a los desarrolladores a ver un objeto de estado predeterminado en el archivo reductor para visualizar lo que está sucediendo. Importa el reductor en el componente para acceder al archivo. Luego, mapStateToProps selecciona solo los pares clave / valor en la tienda que necesita su componente. Piense en ello como Redux creando una versión global de un componente de React
this.state = ({
cats = [],
dogs = []
})
Es imposible cambiar la estructura del estado usando mapStateToProps (). Lo que está haciendo es elegir solo los pares clave / valor de la tienda que el componente necesita y pasar los valores (de una lista de clave / valores en la tienda) a los accesorios (claves locales) en su componente. Haz esto un valor a la vez en una lista. No se pueden producir cambios de estructura en el proceso.
PD: La tienda es un estado local. Los Reductores generalmente también pasan el estado a la base de datos con Action Creators ingresando a la mezcla, pero primero comprenda este concepto simple para esta publicación específica.
PPS Es una buena práctica separar los reductores en archivos separados para cada uno e importar solo el reductor que necesita el componente.
Me gustaría reestructurar la declaración que mencionaste, que es:
Esto significa que el estado consumido por su componente objetivo puede tener una estructura muy diferente del estado almacenado en su tienda.
Puede decir que el estado consumido por su componente de destino tiene una pequeña parte del estado que se almacena en la tienda redux. En otras palabras, el estado consumido por su componente sería el subconjunto del estado de la tienda redux.
En lo que respecta a la comprensión del método connect (), ¡es bastante simple! El método connect () tiene el poder de agregar nuevos accesorios a su componente e incluso anular los accesorios existentes. Es a través de este método de conexión que también podemos acceder al estado de la tienda redux que nos envía el Proveedor. Una combinación de las cuales funciona a su favor y puede agregar el estado de su tienda redux a los accesorios de su componente.
Arriba hay algo de teoría y le sugiero que mire este video una vez para comprender mejor la sintaxis.
Sí, usted puede hacer esto. También puede procesar el estado y devolver el objeto.
function mapStateToProps(state){
let completed = someFunction (state);
return {
completed : completed,
}
}
Esto sería útil si desea cambiar la lógica relacionada con el estado de la función de renderizado a fuera de ella.
La estrella de HGTV, Christina Hall, revela que le diagnosticaron envenenamiento por mercurio y plomo, probablemente debido a su trabajo como manipuladora de casas.
Recientemente salió a la luz un informe policial que acusa a la estrella de 'Love Is Blind', Brennon, de violencia doméstica. Ahora, Brennon ha respondido a los reclamos.
Conozca cómo Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia mientras organizaba la primera celebración de Acción de Gracias desde que murió su madre, Naomi Judd.
Descubra por qué un destacado experto en lenguaje corporal cree que es fácil trazar "tales paralelismos" entre la princesa Kate Middleton y la princesa Diana.
Los inodoros arrojan columnas de aerosol invisibles con cada descarga. ¿Como sabemos? La prueba fue capturada por láseres de alta potencia.
Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?
The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!
¿Sigue siendo efectivo ese lote de repelente de insectos que te quedó del verano pasado? Si es así, ¿por cuánto tiempo?
¿Quiere probar un cepillo de dientes Sonicare sin gastar mucho dinero en uno de sus modelos favoritos de gama alta? Puede comprar un kit de la Serie 2 o Serie 3 por tan solo $ 30 hoy en Amazon. Haga clic aquí para ver la lista completa de modelos elegibles y tenga en cuenta que se descontarán $ 10 adicionales en su carrito.
Tapas elásticas de silicona de Tomorrow's Kitchen, paquete de 12 | $14 | Amazonas | Código promocional 20OFFKINJALids son básicamente los calcetines de la cocina; siempre perdiéndose, dejando contenedores huérfanos que nunca podrán volver a cerrarse. Pero, ¿y si sus tapas pudieran estirarse y adaptarse a todos los recipientes, ollas, sartenes e incluso frutas en rodajas grandes que sobran? Nunca más tendrás que preocuparte por perder esa tapa tan específica.
Hemos pirateado algunas ciudades industriales en esta columna, como Los Ángeles y Las Vegas. Ahora es el momento de una ciudad militar-industrial-compleja.
Un minorista está enlatando su sección de tallas grandes. Pero no están tomando la categoría solo en línea o descontinuándola por completo.
El equipo está a la espera de las medallas que ganó en los Juegos Olímpicos de Invierno de 2022 en Beijing, ya que se está resolviendo un caso de dopaje que involucra a la patinadora artística rusa Kamila Valieva.
Miles de compradores de Amazon recomiendan la funda de almohada de seda Mulberry, y está a la venta en este momento. La funda de almohada de seda viene en varios colores y ayuda a mantener el cabello suave y la piel clara. Compre las fundas de almohada de seda mientras tienen hasta un 46 por ciento de descuento en Amazon
El jueves se presentó una denuncia de delito menor amenazante agravado contra Joe Mixon.
El Departamento de Policía de Lafayette comenzó a investigar a un profesor de la Universidad de Purdue en diciembre después de recibir varias denuncias de un "hombre sospechoso que se acercaba a una mujer".
Al igual que el mundo que nos rodea, el lenguaje siempre está cambiando. Mientras que en eras anteriores los cambios en el idioma ocurrían durante años o incluso décadas, ahora pueden ocurrir en cuestión de días o incluso horas.
Estoy de vuelta por primera vez en seis años. No puedo decirte cuánto tiempo he estado esperando esto.
“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.
Creo, un poco tarde en la vida, en dar oportunidades a la gente. Generosamente.