maverick
maverick

Reputation: 800

Remove "TODO" with redux

I've a simple app built with react/redux. In my "TODO"-app, I can add items and filter them. I've simply just followed this example. But I also tried to add a method that actually removes an item, but it doesn't seem to work.

enter image description here

Actions:

let nextTodoId = 0
export const addTodo = text => {
  return {
    type: 'ADD_TODO',
    id: nextTodoId++,
    text
  }
}

export const setVisibilityFilter = filter => {
  return {
    type: 'SET_VISIBILITY_FILTER',
    filter
  }
}

export const toggleTodo = id => {
  return {
    type: 'TOGGLE_TODO',
    id
  }
}

export const deleteTodo = id => {
  return {
    type: 'DELETE_TODO',
    id: id
  }
}

Reducer:

const todos = (state = [], action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          id: action.id,
          text: action.text,
          completed: false
        }
      ];
    case 'TOGGLE_TODO':
      return state.map(todo =>
          (todo.id === action.id)
              ? {...todo, completed: !todo.completed}
              : todo
      );
    case 'DELETE_TODO':
      return state.filter(todo => todo.id !== action.id);
    default:
      return state
  }
}

export default todos

And in my container:

import React from 'react'
import {connect} from 'react-redux'
import {deleteTodo} from '../actions'

let RemoveTodo = ({dispatch}) => {
  return (
      <div>
        <a onClick={e => {
          e.preventDefault()
          // dispatch(deleteTodo())

          console.log(dispatch(deleteTodo()));
        }}>Remove TODO</a>
      </div>
  )
}

RemoveTodo = connect()(RemoveTodo)

export default RemoveTodo

Components:

import React from 'react'
import PropTypes from 'prop-types'
import {connect} from 'react-redux'
import RemoveTodo from '../containers/RemoveTodo'

export default class Todo extends React.Component {
  constructor(props) {
    super(props);
    this.state;
  }

  render() {
    return (
        <li
            onClick={this.props.onClick}
            className="list-group-item justify-content-between border-c1 c1"
        >
          <span>{this.props.text} {this.props.completed ? <i className="fa fa-check"/> : null}</span>
          <span className="badge c1-bg badge-pill">
            <RemoveTodo />
          </span>
        </li>
    )
  }
}

Todo.propTypes = {
  onClick: PropTypes.func.isRequired,
  completed: PropTypes.bool.isRequired,
  text: PropTypes.string.isRequired,
  id: PropTypes.number.isRequired
}

For some reason, my "dispatch(deleteTodo())" doesn't find the id... When I log it, I simply get an object: type: "DELETE_TODO", id: undefined. Why? What am I missing out here? I'm new to redux/react. Thanks in advance...

EDIT:

When I pass in the id into dispatch(deleteTodo(id)) I get this error:

enter image description here

Upvotes: 0

Views: 6024

Answers (2)

Shubham Khatri
Shubham Khatri

Reputation: 281874

You need to pass the id of todo to the RemoveTodo Component as a prop and then pass it to the action creator like

render() {
    return (
        <li
            onClick={this.props.onClick}
            className="list-group-item justify-content-between border-c1 c1"
        >
          <span>{this.props.text} {this.props.completed ? <i className="fa fa-check"/> : null}</span>
          <span className="badge c1-bg badge-pill">
            <RemoveTodo id={this.props.id} />
          </span>
        </li>
    )
  }

and then

let RemoveTodo = ({id, dispatch}) => {
  return (
      <div>
        <a onClick={e => {
          e.preventDefault()
          dispatch(deleteTodo(id))

          //console.log(dispatch(deleteTodo(id)));
        }}>Remove TODO</a>
      </div>
  )
}

Upvotes: 4

Sagiv b.g
Sagiv b.g

Reputation: 31024

You are not passing the id parameter
This:
dispatch(deleteTodo())
Should be changed to this:
dispatch(deleteTodo(3))

EDIT
As a followup to your comment and edit, you should pass a valid id value or variable that has been defined of course.

Upvotes: 0

Related Questions