I've got a container/component (from Redux
examples) complaining about "dispatch is not a function". I had this working before I added Recompose
. I think Recompose
puts a wrapper around dispatch()
, so I need to expose it somehow. Maybe applyMiddleware
will do the trick, but I don't know where to hook it up? What do I need to do?
Container:
const AddTodo = (props, dispatch) => {
let input;
const { classes } = props;
return (
<div>
<form
id="my-form-id"
onSubmit={e => {
e.preventDefault();
if (!input.value.trim()) {
return;
}
dispatch(addTodo(input.value));//<<<OFFENDING LINE
input.value = "";
}}
>
<TextField
id="agentName"
label="Agent Name"
placeholder="Placeholder"
form="my-form-id"
inputRef={el => (input = el)}
className={classes.textField}
margin="normal"
/>
<Button variant="extendedFab" type="submit" className={classes.button}>
<AddIcon className={classes.addIcon} />
New Todo
</Button>
</form>
</div>
);
};
export default compose(
withStyles(styles),
connect()
)(AddTodo);
Root index.js:
import React from "react";
import { render } from "react-dom";
import { createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import App from "./components/App";
import rootReducer from "./reducers";
const store = createStore(rootReducer);
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);
There are two basic things to understand.
1.
When composing connect()
Redux adds dispatch as a prop.
export default compose(
withStyles(styles),
connect() // <-- This adds dispatch to props.
)(AddTodo);
2.
You should access props
as a single object or destructure branches of the props object.
This line is where the misunderstanding is happening.
const AddTodo = (props, dispatch) => { // <-- dispatch is not an parameter, it exists at props.dispatch
To fix things using your existing pattern do this.
const AddTodo = (props) => {
let input;
const { classes, dispatch } = props;
return (
...
Optionally you can destructure the props parameter directly.
const AddTodo = ({ classes, dispatch }) => {
let input;
return (
...
With either approach the remaining code will work as expected.