reactjs - pasar - Redux, ¿tengo que importar la tienda en todos mis contenedores si quiero tener acceso a los datos?
react comunicacion entre componentes (2)
Tal vez no estoy pensando en redux, pero todos los ejemplos que he visto realmente no acceden demasiado al estado entre contenedores y, por lo tanto, no he visto mucho uso de store.getState (), pero incluso si quieres despacho, necesita acceso a la tienda, ¿verdad?
Entonces, aparte de importar la tienda de importación desde ''ruta / a / tienda / tienda''
en cada archivo que quiero obtener Estado () o "despacho", ¿cómo obtengo acceso a ese estado porque si no lo incluyo, la tienda no está definida?
En general, solo desea hacer que los componentes de contenedor de nivel superior tengan acceso a la tienda: transmitirán los datos necesarios o los despachos de acción como accesorios a sus componentes secundarios. Esta es la diferencia entre un componente "inteligente" y uno "tonto": los componentes "inteligentes" conocen la tienda / estado de Redux, mientras que los componentes "tontos" solo reciben accesorios y no tienen idea del estado de la aplicación más grande.
Sin embargo, incluso pasar la tienda a los componentes del contenedor puede volverse tedioso.
Es por eso que React-Redux proporciona un componente listo para usar que envuelve toda su aplicación.
Compruébalo
en los documentos.
Este es el componente
Provider
y cuando envuelve toda su aplicación con él, solo pasa la tienda a un componente
una vez
:
import createStore from ''../store'';
const store = createStore()
class App extends Component {
render() {
return (
<Provider store={store}>
<MainAppContainer />
</Provider>
)
}
}
Como puede ver aquí, tengo un archivo de configuración separado solo para mi tienda, ya que hay muchas modificaciones que puede hacer y para cualquier aplicación remotamente compleja, se encontrará haciendo lo mismo para cosas como usar compose para aplicar middleware.
Entonces, cualquiera de sus componentes "inteligentes" restantes (generalmente envoltorios) necesita escuchar la tienda. Esto se logra utilizando el método de connect . Esto le permite asignar partes del estado a las propiedades de sus componentes, así como distribuir acciones como propiedades.
import { bindActionCreators } from ''redux'';
import { connect } from ''react-redux'';
import * as actionCreators from ''./actionCreators'';
const mapStateToProps = function(state){
return {
something: state.something,
}
}
const mapDispatchToProps = function (dispatch) {
return bindActionCreators({
getSomething: actionCreators.getSomething,
}, dispatch)
}
class MainAppContainer extends Component {
componentDidMount() {
//now has access to data like this.props.something, which is from store
//now has access to dispatch actions like this.props.getSomething
}
render() {
//will pass down store data and dispatch actions to child components
return (
<div>
<ChildComponent1 something={this.props.something} />
<ChildComponent2 getSomething={this.props.getSomething} />
</div>
)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(MainAppContainer)
Debido a que siempre está transmitiendo acciones de despacho y datos a su componente
this.props
como propiedades, solo debe hacer referencia a aquellos en ese componente con
this.props
.
A partir del ejemplo anterior, verá que porque pasé
this.props.something
a
ChildComponent1
, tiene acceso a los datos de la tienda, pero no tiene acceso a la acción de envío
getSomething
.
Del mismo modo,
ChildComponent2
solo tiene acceso a la acción de envío
getSomething
pero no a los datos de
something
.
Esto significa que solo expone los componentes a exactamente lo que necesitan de la tienda.
Por ejemplo, debido a que
ChildComponent2
pasó la acción de envío como
getSomething
, en mi
onClick
puedo llamar a
this.props.getSomething
y llamará a la acción de envío
sin necesidad de tener acceso a la tienda
.
De la misma manera, puede continuar transmitiendo
getSomething
a otro componente secundario y ese componente podría llamarlo y / o transmitirlo y el ciclo podría continuar indefinidamente.
class ChildComponent2 extends Component {
render() {
return (
<div>
<div onClick={this.props.getSomething}>Click me</div>
<NestedComponent getSomething={this.props.getSomething} />
</div>
)
}
}
Editar desde los comentarios
Si bien esto no pertenece directamente a la pregunta, en los comentarios parecía un poco confundido acerca de las acciones.
En realidad no
getSomething
la acción
getSomething
aquí.
En cambio, es habitual en las aplicaciones de Redux colocar todas sus definiciones de acción en un archivo separado llamado
actionCreators.js
.
Contiene funciones que reciben el mismo nombre que sus acciones y devuelven un objeto con una propiedad de
type
y cualquier otro método / dato que requiera la acción.
Por ejemplo, aquí hay un ejemplo muy simple de archivo
actionCreators.js
:
export function getSomething() {
return {
type: ''GET_SOMETHING'',
payload: {
something: ''Here is some data''
}
}
}
Este tipo de acción es lo que su reductor escucharía para saber qué acción se estaba disparando.
Si usa el paquete
react-redux
, terminará envolviendo sus componentes en un
Provider
con un accesorio de la
store
.
Esto configura su tienda individual en un contexto React, al que luego se accede desde el método de
connect
en componentes secundarios.
El método de
connect
toma dos funciones (mapStateToProps y mapDispatchToProps), que son sus ganchos para obtener el estado de la tienda y enviar mensajes.