Some problems with context api in my todo app

hey guys the problem is that when I click submit nothing is getting sent to my context state.

Context state in App.js

const [todo, setTodo] = useState([]);

data sent from TodoForm

const [todoDetail,setTodoDetail] = useState();
const {todo,setTodo} = useContext(IDContext);
    
    const handleSubmit =(e)=>{
        e.preventDefault();
        // if(todoDetail.task.length>=1){
            setTodo({...todoDetail,id:uuid()})
        // }
    }

code: https://codesandbox.io/s/particles-transition-forked-fgtqv?file=/src/components/TodoForm.js

bump

<form>
  <input type="text" onChange={handleChange}/>
  <button type="submit" onSubmit={handleSubmit}>Submit</button>
</form>

onSubmit have to be used on form element. MDN: Form

When you change this, your context will get updated. There is still one more problem though but once you see the value of the context you should be able to figure it out :wink:

1 Like

thanks man, is the other problem is that when i submit the site refreshes and everything is gone? should i put the context in local storage?

The site refreshes because that’s the default behaviour when submitting the form. That’s why we use event.preventDefault().

In your code however even though there is event.preventDefault() it still refreshes when submitting the form. It most likely means that handleSubmit was not called. The reason it was not called is because onSubmit doesn’t work on button elements but instead have to be used on form element.

Once you fix this, the site shouldn’t refresh anymore.

1 Like

thanks for the detailed answer :pray:

I did this and in my console it shows my context got the info but im wondering why my .map is not working and taking the info from the todo context.

Yeah, that’s the other issue I was talking about.

Have you tried console.logging the item to see how does it look like before mapping over it?

1 Like

yes im getting it saves the present info but doesnt save the past infos so i think i shuld put it in local storage

export default function TodoList() {
  const { todo } = useContext(IDContext);

  // How does `todo` look like here? 
  console.log(todo);

  return (
    <div>
      {todo.length >= 1
        ? todo.map((todoItems) => <Todo key={todoItems.id} todo={todoItems} />)
        : null}
    </div>
  );
}

{task: "sfdsf", completed: false, id: "a379bb55-3e36-46bd-a62f-321a3ed2c495"}

Okay so todo is an OBJECT.

Does that ring a bell for you?

aha yea i should change it json or an array right

Let’s leave JSON, because it has nothing to do with it :slight_smile:

You’re trying to access length property and then use map method so you need todo to be an array not an object.

And actually you even initialized your todo to be an empty array here:

const [todo, setTodo] = useState([]);

So somewhere in the process you changed that array to be an object. You’ll have to find where.

PS I think it would be reasonable to rename todo to todos if you want to store multiple items. It’s not obligatory but I think it’d be more readable and easier to debug.

1 Like