1

I try to do Todo App, I stack on add existing pending task to completed task. How can i add existing item to new state in reducer or there is a another way to do that? When i click the button which has completed id, i want to push that task to completed state.

Main:

const App = () => {

  const [state, dispatch] = useReducer(todoAppReducer, [])

  return (
    <TodoAppContext.Provider value={{
      state: state,
      dispatch,
    }}>
      <BrowserRouter>
          <Header/>
          <AddTask />
          <Sections />
              <Routes>
                  <Route path=''  element={ <Pending /> }/>
                  <Route path='completed'  element={ <Completed /> }/>
                  <Route path='deleted'  element={ <Deleted /> }/>
              </Routes>
      </BrowserRouter>
    </TodoAppContext.Provider>
  )
}

export default App

Add Task:

const AddTask = () => {
  const {dispatch} = useContext(TodoAppContext)
  const [task, setTask] = useState("");
  const [taskDetail, setTaskDetail] = useState("");
  const [error, setError] = useState("")

  const onAddTaskSubmit = (e) => {
    e.preventDefault();
    if(task == "") {
      setError("Please enter task!")
    } else {
      dispatch({
        type: 'ADD_PENDING',
        task,
        taskDetail
      })
      setError("")
    }
    setTask("")
    setTaskDetail("")
  }

  return (
      <div className='non-bootstrap-container add-task-form'>
          <form onSubmit={onAddTaskSubmit}>
            <input value={task} onChange={(e) => setTask(e.target.value)} type="text" placeholder='Enter Task'/>
            <textarea value={taskDetail} onChange={(e) => setTaskDetail(e.target.value)} placeholder='Task Details (Optional)'></textarea>
            <div className='add-button-and-error'>
              <p className='error'>{error}</p>
              <button type='submit' className='btn btn-primary'>Add Task</button>
            </div>
          </form>
      </div>
  )
}

export default AddTask

Reducer

const todoAppReducer = (state, action) => {
    switch(action.type) {
        case "ADD_PENDING":
            return [
                ...state,
                {title: action.task, detail: action.taskDetail}
            ]
        default:
            return state
    }
}

export default todoAppReducer

When i click the button which has completed id, i want to push that task to completed state.

const Pending = () => {
    const {state} = useContext(TodoAppContext)

    return (
        <div className='non-bootstrap-container tasks'>
            {
                <ul>
                    {   
                        state.map((task,index) => (
                            <li key={index}>
                                <div>
                                    <span>{index}. </span>
                                    <span>{task.title}</span>
                                </div>
                                <span>{task.detail}</span>
                                <div>
                                <button className='btn btn-primary' id='completed'><i className="fa-solid fa-check"></i></button>
                                <button className='btn btn-danger'><i className="fa-solid fa-trash-can"></i></button>
                                </div>
                            </li>
                        ))
                    }
                </ul>
            }
        </div>
    )
}

export default Pending
Yahya
  • 11
  • 1

1 Answers1

0

You first need to set the case in the reducer.

Reducer

case "COMPLETED":
            return [
                ...state,
                {title: action.task, detail: action.taskDetail}
            ]

Now try calling it in submit button when the task is completed with dispatch.

Hope it helps! =)

Shameel Uddin
  • 511
  • 2
  • 10