0

I am developing a TODO app using react redux typescript. I am unable to dispatch an action. I am new to redux so stuck in it. I am creating an event onclick handleSubmitButton then it is throwing dispatch error. Can someone help me in that ?

AddToDo.tsx

const AddToDo: React.FC = () => {
    const [inputValue, setInputValue] = useState<string>("");

    const handleSubmitButton = (e: React.MouseEvent<HTMLButtonElement>)=> {
        e.preventDefault()
        console.log(inputValue, "inputValue");
        dispatch(addTodo(inputValue))
    }

    return (
        <div>
            <form noValidate>
                <div className="form-group">
                    <label htmlFor="todoitem">Todo Item:</label>
                    <input type="text" className="form-control" placeholder="Enter Text" value={inputValue} id="todoitem" onChange={handleEditTodoItem} />
                </div>
                <button type="submit" className="btn btn-primary" onClick={handleSubmitButton}>Submit</button>
            </form>
        </div>
    )
}

export default connect()(AddToDo)

Below is my action code -

export const addTodo = (name: string): AddTodoAction => (
   {
    type: ActionTypes.ADD_TODO,
    payload: {
      todo: {
        id: nextId++,
        name: name,
        done: false
      }
    }
  }
)

and Now my reducer code -

export function reducer(state: State = initialState, action: Action) {

  switch (action.type) {
    case ActionTypes.ADD_TODO: {

      const todo = action.payload.todo

      return {
        ...state,
        todos: [...state.todos, todo]
      }
    }
}
}

2 Answers 2

2

The reason you are getting a "dispatch error" is because dispatch is probably undefined. This is because you failed to:

import { useDispatch } from 'react-redux'
// ...
const dispatch = useDispatch();

If using the hooks to hook into redux, you don't need to "connect" anything, nor write mapDispatchToProps. Just useSelector and useDispatch are enough to hook into the redux store, which makes for a much friendlier experience.

Sign up to request clarification or add additional context in comments.

Comments

0

This answer is based on not using Redux hooks. You are close, but you forgot to import your dispatch in connect() using mapDispatchToProps. This would look like something like this:

import { Dispatch } from 'redux';
import { addToDo } from '../action'; // replace this import with the correct path to your action

    type AddToDoProps = {
       addToDo: (inputValue: string) => void;
    }

    const AddToDo: React.FC<AddToDoProps> = ({ addToDo }) => {
    const [inputValue, setInputValue] = useState<string>("");

    const handleSubmitButton = (e: React.MouseEvent<HTMLButtonElement>)=> {
        e.preventDefault()
        console.log(inputValue, "inputValue");
        addTodo(inputValue)
    }

    return (
        <div>
            <form noValidate>
                <div className="form-group">
                    <label htmlFor="todoitem">Todo Item:</label>
                    <input type="text" className="form-control" placeholder="Enter Text" value={inputValue} id="todoitem" onChange={handleEditTodoItem} />
                </div>
                <button type="submit" className="btn btn-primary" onClick={handleSubmitButton}>Submit</button>
            </form>
        </div>
    )
}

const mapDispatchToProps = (dispatch: Dispatch) => ({
   addToDo: (inputValue: string) => dispatch(addToDo(inputValue))
})

export default connect(null, mapDispatchToProps)(AddToDo)

Note: You are getting your dispatch method as a prop in your component which means you will have to define this prop in Typescript.

type AddToDoProps = {
  addToDo: (inputValue: string) => void;
}

Add this type to your component and define your dispatch prop in order to use it:

const AddToDo: React.FC<AddToDoProps> = ({ addToDo }) => ...

3 Comments

The redux hooks make life much easier now (athough keeping redux dependencies out of your visual components makes for much easier testing, so it's a mixed blessing).
Oh I just checked the docs and indeed the redux approach with hooks seems to be a lot easier. I'll leave this answer for people that aren't using hooks. Thanks for letting me know tho!
I'm still torn on whether or not they are a good idea. This nice thing about this approach is that the visual component is entirely standalone from the connecting HOC. I suppose a similar model can be used with hooks by using a separate component for wiring-up of redux.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.