javascript - tipos - ''dispatch'' no es una función cuando el argumento de mapToDispatchToProps() en Redux
tipos de argumentacion (11)
Problema
Aquí hay un par de cosas a tener en cuenta para comprender el comportamiento del componente conectado en su código:
La Arity de
connect
Matters:
connect(mapStateToProps, mapDispatchToProps)
Las llamadas React-Redux se
connect
con el primer argumento
mapStateToProps
y el segundo argumento
mapDispatchToProps
.
Por lo tanto, aunque haya pasado en su
mapDispatchToProps
, React-Redux de hecho lo trata como
mapState
porque es el primer argumento.
Todavía obtiene la función
onSubmit
inyectada en su componente porque el retorno de
mapState
se
mapState
en los accesorios de su componente.
Pero no es así como se debe inyectar
mapDispatch
.
Puede usar
mapDispatch
sin definir
mapState
.
Pase
null
en lugar de
mapState
y su componente no estará sujeto a cambios en la tienda.
El componente conectado recibe el
dispatch
de forma predeterminada, cuando no se proporciona
mapDispatch
Además, su componente recibe
dispatch
porque recibió
null
para su segunda posición para
mapDispatch
.
Si pasa correctamente en
mapDispatch
, su componente no recibirá el
dispatch
.
Práctica común
Lo anterior responde por qué el componente se comportó de esa manera.
Sin embargo, es una práctica común que simplemente pase a su creador de acciones utilizando la
mapStateToProps
de objeto de
mapStateToProps
.
Y llame a eso dentro de
onSubmit
su componente Eso es:
import { setAddresses } from ''../actions.js''
const Start = (props) => {
// ... omitted
return <div>
{/** omitted */}
<FlatButton
label=''Does Not Work''
onClick={this.props.setAddresses({
pickup: this.refs.pickup.state.address,
dropoff: this.refs.dropoff.state.address
})}
/>
</div>
};
const mapStateToProps = { setAddresses };
export default connect(null, mapDispatchToProps)(Start)
Soy un principiante javascript / redux / react construyendo una pequeña aplicación con redux, react-redux, y react. Por alguna razón, cuando uso la función mapDispatchToProps en conjunto con connect (enlace react-redux), recibo un TypeError que indica que el despacho no es una función cuando intento ejecutar el accesorio resultante. Sin embargo, cuando llamo a dispatch como accesorio (vea la función setAddr en el código provisto) funciona.
Tengo curiosidad por saber por qué esto es así, en el ejemplo de la aplicación TODO en los documentos redux, el método mapDispatchToProps se configura de la misma manera. Cuando console.log (dispatch) dentro de la función dice que dispatch es type object. Podría seguir usando el despacho de esta manera, pero me sentiría mejor sabiendo por qué sucede esto antes de continuar con redux. Estoy usando webpack con babel-loaders para compilar.
Mi código:
import React, { PropTypes, Component } from ''react'';
import { connect } from ''react-redux'';
import { setAddresses } from ''../actions.js'';
import GeoCode from ''./geoCode.js'';
import FlatButton from ''material-ui/lib/flat-button'';
const Start = React.createClass({
propTypes: {
onSubmit: PropTypes.func.isRequired
},
setAddr: function(){
this.props.dispatch(
setAddresses({
pickup: this.refs.pickup.state.address,
dropoff: this.refs.dropoff.state.address
})
)
},
render: function() {
return (
<div>
<div className="row">
<div className="col-xs-6">
<GeoCode ref=''pickup'' />
</div>
<div className="col-xs-6">
<GeoCode ref=''dropoff'' />
</div>
</div>
<div className="row">
<div className="col-xs-6">
<FlatButton
label=''Does Not Work''
onClick={this.props.onSubmit({
pickup: this.refs.pickup.state.address,
dropoff: this.refs.dropoff.state.address
})}
/>
</div>
<div className="col-xs-6">
<FlatButton
label=''Works''
onClick={this.setAddr}
/>
</div>
</div>
</div>
);
}
})
const mapDispatchToProps = (dispatch) => {
return {
onSubmit: (data) => {
dispatch(setAddresses(data))
}
}
}
const StartContainer = connect(mapDispatchToProps)(Start)
export default StartContainer
Aclamaciones.
Cuando no proporciona
mapDispatchToProps
como segundo argumento, así:
export default connect(mapStateToProps)(Checkbox)
entonces recibirá automáticamente el envío a los accesorios del componente, por lo que puede simplemente:
class SomeComp extends React.Component {
constructor(props, context) {
super(props, context);
}
componentDidMount() {
this.props.dispatch(ACTION GOES HERE);
}
....
sin ningún mapaDispatchToProps
En algún momento, este error también se produce cuando cambia el orden de la función Componente mientras pasa a conectarse.
Orden incorrecta:
export default connect(mapDispatchToProps, mapStateToProps)(TodoList);
Orden correcto:
export default connect(mapStateToProps,mapDispatchToProps)(TodoList);
Estoy usando así ... es fácil de entender el primer argumento es mapStateToProps y el segundo argumento es mapDispatchToProps al final se conecta con la función / clase.
const mapStateToProps = (state) => {
return {
todos: getVisibleTodos(state.todos, state.visibilityFilter)
}
}
const mapDispatchToProps = (dispatch) => {
return {
onTodoClick: (id) => {
dispatch(toggleTodo(id))
}
}
}
export default connect(mapStateToProps,mapDispatchToProps)(TodoList);
La función React-redux ''connect'' acepta dos argumentos primero es mapStateToProps y segundo es mapDispatchToProps verifique debajo de ej.
export default connect(mapStateToProps, mapDispatchToProps)(Index);
``
Si no queremos recuperar el estado de redux, establecemos nulo en lugar de mapStateToProps.
export default connect(null, mapDispatchToProps)(Index);
Lo resolví intercambiando los argumentos, estaba usando
export default connect(mapDispatchToProps, mapStateToProps)(Checkbox)
Cuál está mal.
El
mapStateToProps
tiene que ser el primer argumento:
export default connect(mapStateToProps, mapDispatchToProps)(Checkbox)
Parece obvio ahora, pero podría ayudar a alguien.
Necesitaba un ejemplo usando
React.Component
así que lo estoy publicando:
import React from ''react'';
import * as Redux from ''react-redux'';
class NavigationHeader extends React.Component {
}
const mapStateToProps = function (store) {
console.log(`mapStateToProps ${store}`);
return {
navigation: store.navigation
};
};
export default Redux.connect(mapStateToProps)(NavigationHeader);
Si desea usar
mapDispatchToProps
sin
mapStateToProps
use
null
para el primer argumento.
export default connect(null, mapDispatchToProps)(Start)
Solo te falta el primer argumento para
connect
, que es el método
mapStateToProps
.
Extracto de la aplicación Redux todo:
const mapStateToProps = (state) => {
return {
todos: getVisibleTodos(state.todos, state.visibilityFilter)
}
}
const mapDispatchToProps = (dispatch) => {
return {
onTodoClick: (id) => {
dispatch(toggleTodo(id))
}
}
}
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
Una trampa que algunos podrían enfrentar está cubierta por esta pregunta, pero no se aborda en las respuestas, ya que es ligeramente diferente en la estructura del código pero devuelve exactamente el mismo error.
Este error ocurre cuando se usa
bindActionCreators
y no se pasa la función de
dispatch
Código de error
import someComponent from ''./someComponent''
import { connect } from ''react-redux'';
import { bindActionCreators } from ''redux''
import { someAction } from ''../../../actions/someAction''
const mapStatToProps = (state) => {
const { someState } = state.someState
return {
someState
}
};
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({
someAction
});
};
export default connect(mapStatToProps, mapDispatchToProps)(someComponent)
Código fijo
import someComponent from ''./someComponent''
import { connect } from ''react-redux'';
import { bindActionCreators } from ''redux''
import { someAction } from ''../../../actions/someAction''
const mapStatToProps = (state) => {
const { someState } = state.someState
return {
someState
}
};
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({
someAction
}, dispatch);
};
export default connect(mapStatToProps, mapDispatchToProps)(someComponent)
Faltaba el
dispatch
funciones en el código de error
Utilizar
const StartContainer = connect(null, mapDispatchToProps)(Start)
en vez de
const StartContainer = connect(mapDispatchToProps)(Start)