javascript - react - ¿Cómo obtener un envío simple de this.props usando connect w/Redux?
redux saga (3)
Tengo un componente React simple que conecto (mapeo de una matriz / estado simple). Para evitar hacer referencia al contexto de la tienda, me gustaría una forma de obtener el "envío" directamente desde los accesorios. He visto a otros usar este enfoque pero no tengo acceso a esto por alguna razón :)
Aquí están las versiones de cada dependencia npm que estoy usando actualmente
"react": "0.14.3",
"react-redux": "^4.0.0",
"react-router": "1.0.1",
"redux": "^3.0.4",
"redux-thunk": "^1.0.2"
Aquí está el componente con el método de conexión
class Users extends React.Component {
render() {
const { people } = this.props;
return (
<div>
<div>{this.props.children}</div>
<button onClick={() => { this.props.dispatch({type: ActionTypes.ADD_USER, id: 4}); }}>Add User</button>
</div>
);
}
};
function mapStateToProps(state) {
return { people: state.people };
}
export default connect(mapStateToProps, {
fetchUsers
})(Users);
Si necesita ver el reductor (nada emocionante, pero aquí está)
const initialState = {
people: []
};
export default function(state=initialState, action) {
if (action.type === ActionTypes.ADD_USER) {
let newPeople = state.people.concat([{id: action.id, name: ''wat''}]);
return {people: newPeople};
}
return state;
};
Si necesita ver cómo está configurado mi enrutador con redux
const createStoreWithMiddleware = applyMiddleware(
thunk
)(createStore);
const store = createStoreWithMiddleware(reducers);
var Route = (
<Provider store={store}>
<Router history={createBrowserHistory()}>
{Routes}
</Router>
</Provider>
);
actualizar
parece que si omito mi propio envío en la conexión (actualmente arriba estoy mostrando fetchUsers), obtendría envío gratis (solo que no estoy seguro de si así es como funcionaría normalmente una configuración con acciones asincrónicas). ¿La gente se mezcla y combina o es todo o nada?
[mapDispatchToProps]
Por defecto,
mapDispatchToProps
es solo
dispatch => ({ dispatch })
.
Entonces, si no especifica el segundo argumento para
connect()
, se le inyectará el
dispatch
como accesorio en su componente.
Si pasa una función personalizada a
mapDispatchToProps
, puede hacer cualquier cosa con la función.
Algunos ejemplos:
// inject onClick
function mapDispatchToProps(dispatch) {
return {
onClick: () => dispatch(increment())
};
}
// inject onClick *and* dispatch
function mapDispatchToProps(dispatch) {
return {
dispatch,
onClick: () => dispatch(increment())
};
}
Para ahorrarle algo de escritura, Redux proporciona
bindActionCreators()
que le permite activar esto:
// injects onPlusClick, onMinusClick
function mapDispatchToProps(dispatch) {
return {
onPlusClick: () => dispatch(increment()),
onMinusClick: () => dispatch(decrement())
};
}
dentro de esto:
import { bindActionCreators } from ''redux'';
// injects onPlusClick, onMinusClick
function mapDispatchToProps(dispatch) {
return bindActionCreators({
onPlusClick: increment,
onMinusClick: decrement
}, dispatch);
}
o incluso más corto cuando los nombres de utilería coinciden con los nombres de los creadores de acciones:
// injects increment and decrement
function mapDispatchToProps(dispatch) {
return bindActionCreators({ increment, decrement }, dispatch);
}
Si lo desea, definitivamente puede agregar el
dispatch
a mano:
// injects increment, decrement, and dispatch itself
function mapDispatchToProps(dispatch) {
return {
...bindActionCreators({ increment, decrement }), // es7 spread syntax
dispatch
};
}
No hay asesoramiento oficial sobre si debe hacer esto o no.
connect()
generalmente sirve como el límite entre los componentes con reconocimiento de Redux y sin conocimiento de Redux.
Es por eso que generalmente sentimos que no tiene sentido inyectar
tanto
creadores de acciones vinculadas como
dispatch
.
Pero si siente que necesita hacer esto, no dude en hacerlo.
Finalmente, el patrón que está utilizando en este momento es un acceso directo que es incluso más corto que llamar a
bindActionCreators
.
Cuando todo lo que haces es devolver
bindActionCreators
, puedes omitir la llamada, así que en lugar de hacer esto:
// injects increment and decrement
function mapDispatchToProps(dispatch) {
return bindActionCreators({ increment, decrement }, dispatch);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(App);
se puede escribir así
export default connect(
mapStateToProps,
{ increment, decrement } // injects increment and decrement
)(App);
Sin embargo, tendrá que renunciar a esa sintaxis corta y agradable siempre que desee algo más personalizado, como pasar el
dispatch
también.
Por lo general, puede mezclar y combinar según lo que desee.
Puede pasar el
dispatch
como accesorio si eso es lo que desea:
export default connect(mapStateToProps, (dispatch) => ({
...bindActionCreators({fetchUsers}, dispatch), dispatch
}))(Users);
No estoy seguro de cómo se usa
fetchUsers
(como una función asíncrona), pero generalmente usaría algo como
bindActionCreators
para
bindActionCreators
automáticamente el
envío y luego no tendría que preocuparse por usar el
dispatch
directamente en los componentes conectados.
El uso del directorio de
dispatch
combina el componente
tonto
sin estado con redux.
Lo que puede hacerlo menos portátil.
Si bien puede pasar el
dispatch
hacia abajo como parte de
dispatchToProps
, recomendaría evitar acceder a la
store
o
dispatch
directamente desde sus componentes.
Parece que sería mejor que pases a un creador de acciones vinculadas en el segundo argumento
dispatchToProps
connect
Vea un ejemplo que publiqué aquí https://.com/a/34455431/2644281 de cómo transmitir un "creador de acciones ya vinculado" de esta manera sus componentes no necesitan saber directamente o depender de la tienda / despacho .
Perdón por ser breve. Actualizaré con más información.