'Lesson Review' for 'The State Hook'

I’m trying to complete the ‘Lesson Review’ for ‘The State Hook’.
Link: https://www.codecademy.com/courses/react-101/lessons/the-state-hook/exercises/lesson-review

But I keep getting the following error message:

“Oops! The test returned an error. Maybe you have a syntax error, or a typo. See full error.”

The “full error” isn’t any more useful/helpful than the original error message. And checking the JavaScript console doesn’t display any useful information, either.

UPDATE - I ended up creating a React project, so I could get a better idea of what’s going on with the code. So after making some changes, the app does render, but I get an error page when I try to enter the name of a new task.

And when I click the ‘Run’ button on the Web page for the current lesson, I get the following error message:

"Manage the state of the title and description for a new task in your component. "

Not sure what that means exactly, I thought I just had to manage state for the ‘newTask’ object and the ‘allTasks’ array.

1 Like

Hello, you can post a copy of your code by giving us the link generated from clicking Share Code at the bottom:
image

From the sound of the update you posted, the flow between your component and isn’t quite there. You mentioned that you get an error when you enter the name of a task - what was the error?

I took a look at the tests they perform when you click Run, and that particular message is at the beginning of a section of tests after “type in a new task”. It compares the value they typed and the value being stored by the component.

I suspect the event handler (probably called handleChange) passed down could be at fault, but we’ll know more once you post your code.

I’m not seeing the ‘Share Code’ icon.

Here’s the code:

import React, { useState } from “react”;
import NewTask from “…/Presentational/NewTask”;
import TasksList from “…/Presentational/TasksList”;

export default function AppFunction() {
// hook your code up here :wink:
const [newTask, setNewTask] = useState({});
const [allTasks, setAllTasks] = useState();

const handleChange = ({ target }) => {
const { name, value } = target;
let newTaskObject = {
[name]: value,
id: Date.now()
};
setNewTask(newTaskObject);
setAllTasks([…allTasks, newTaskObject]);
// setAllTasks((prevState) => ({
// …prevState,
// newTaskObject
// }));
}

const handleSubmit = (event) => {
event.preventDefault();
if (!newTask.title) return;
setAllTasks((prevState) => Object.assign(prevState.allTasks, prevState.newTask));
setNewTask({});
}

const handleDelete = (taskIdToRemove) => {
// setAllTasks((prevState) => ({
// …prevState,
// prevState.allTasks.filter((task) => task.id !== taskIdToRemove)
// }));
}

return (

Tasks





);
}

The way you posted your code makes it very difficult to read and even impossible to read in some spots where you’re using JSX (like in what I quoted above), so it can’t be effectively reviewed. You can use the option I mentioned in my first response, or you could use the option built into the forum: image

First thing I notice is that you’re using setAllTasks in your handleChange event, but that is the event called as the user types in the box before submitting, so definitely shouldn’t be adding it to the list of tasks in there. I’ll be able to assist more once you repost the code

import React, { useState } from "react";
import NewTask from "../Presentational/NewTask";
import TasksList from "../Presentational/TasksList";

export default function AppFunction() {
  // hook your code up here ;)
  const [newTask, setNewTask] = useState({});
  const [allTasks, setAllTasks] = useState([]);

  const handleChange = ({ target }) => {
    const { name, value } = target;
    let newTaskObject = {
        [name]: value,
        id: Date.now()
    };
    setNewTask(newTaskObject);
    setAllTasks((prevState) => ({
      ...prevState,
      newTaskObject
    }));
  }

  const handleSubmit = (event) => {
    event.preventDefault();
    if (!newTask.title) return;
    setAllTasks((prevState) => Object.assign(allTasks, newTask));
    setNewTask({});
  }

  const handleDelete = (taskIdToRemove) => {
    // setAllTasks((prevState) => ({
    //   ...prevState,
    //   prevState.allTasks.filter((task) => task.id !== taskIdToRemove)
    // }));
  }

  return (
    <main>
      <h1>Tasks</h1>
      <NewTask
        newTask={newTask}
        handleChange={handleChange}
        handleSubmit={handleSubmit}
      />
      <TasksList
        allTasks={allTasks}
        handleDelete={handleDelete}
      />
    </main>
  );
}```

There are a few areas you’ll need to adjust:

  • You don’t need to call setAllTasks from your handleChange() function. This function is used as an event handler by the NewTask component for its text fields as the user types, so it gets fired every character. This call needs to be removed. (Note: You removing this will fix your crash too because you’re incorrectly converting allTasks to an object with the way you’re calling setAllTasks, so it causes the TasksLists component to fail)

  • The way you are using setNewTask in handleChange() causes it to replace the entire object rather than combine it with and update the existing one. It’s important to update the values rather than replacing it with a new object because the NewTask component uses this function as an event handler for 2 fields: title and description. This means that as you type in the title of the task, it will seem to work correctly, but as soon as you start typing in the description, the title is be made blank again because the title property will no longer exist in the object.
    You could use setNewTask with a callback function to access the previous state and the spread operator ... to retain the old values.

  • In your handleSubmit() function, you need to keep in mind that allTasks is an array of the tasks. In your callback to setAllTasks you can return an array that includes newTask with the other values already in the array. Consider using the spread operator ... for this too.

Also, your code for handleDelete() is commented out so I won’t go into detail, but keep in mind that allTasks is an array when you go back to tackle this.

I’m getting the same error with this code. Is there something I’m missing that I’m just not able to see?
And for some reason no matter how I change the index.js file, the same Tasks page is rendered & working even though it shouldn’t be.

@ananyakaushik4215549 hello, and welcome to the forums!

   const handleSubmit = (event) => {
    event.preventDefault();
    if (!newTask.title) return;
    setAllTasks(prevAllTasks => [...prevAllTasks, newTask]);
    
  const handleDelete = (taskIdToRemove) => {

It looks like you’re missing a curly brace to end the handleSubmit function properly. One more thing is that the class version of the component added new tasks to the front of the array rather than to the end like you’re doing. Not sure if that is a requirement though.

You’re importing the same NewTask and TasksList components that the class version uses (which you’re supposed to do). Is that what you were referring to being the same? You shouldn’t need to modify those. The purpose of the lesson is to take an existing class component and create a function component in its place with the same functionality, even working with the components that were already there.

Thank you! I don’t know how I missed that :slight_smile:
I’m still getting the same error, though and I’ve changed the handleSubmit method too just in case.

I guess my doubt was more wrt to the page that loads when you run your code. Even though my code seem to not work now, the UI loads the same Tasks page from before and still works (even if I change the index.js directly to something else). But I guess it doesn’t matter, because in the end I have to get my code working.

I understand what you mean about the UI looking the same now.

Short Reason: An error in your code is causing the browser in the learning environment to use old code, so you aren’t seeing newer changes.

Longer Reason I pasted your AppFunction.js code into my project and didn’t see the different <h1> title that you entered. Behind the scenes, an index.compiled.js is being created with the code in the project each time we press Run in the editor. However, there is an error in your code that is preventing it from making a new version of index.compiled.js, but the editor isn’t saying that and anything in the console will be from the previously compiled code. If you wee developing locally, there would be more errors displayed to help troubleshoot.

How To Fix You need to review this code block:

  const handleDelete = (taskIdToRemove) => {
    setAllTasks(prevAllTasks => ({
      prevAllTasks.filter(task => task.id !== taskIdToRemove);
    }));
  }

If you comment out the block inside the function, you’ll see changes in your application again

  const handleDelete = (taskIdToRemove) => {
    // setAllTasks(prevAllTasks => ({
    //  prevAllTasks.filter(task => task.id !== taskIdToRemove);
    // }));
  }

As for how to fix that commented out block, remember that you should be setting All Tasks to an array. Right now your parenthesis around the curly braces are causing it to attempt to return an object. Let me know if you need more details. Your trick of changing the value of the H1 is good though, and you can keep doing that to make sure whatever you are changing inside handleDelete isn’t stopping you from seeing the new version.

1 Like

That absolutely did it - got it working now! Also you short + long reasons really help, I was so confused by what was going & even thought my code was producing the right results at first. Makes so much more sense now, thank you so much!

1 Like

hi so im also getting the same error:

but i don’t know what to change in the AppFunction . I think this is creating a bug that whenever i try to submit my new task it doesn’t shows up as a task. Here is my code: