Passing Thoughts - No deletion after time has elapsed

Morning all,

I’m currently having issues with the Passing Thoughts project.
Link: (https://www.codecademy.com/paths/full-stack-engineer-career-path/tracks/fscp-react-part-ii/modules/fecp-function-components-and-hooks/projects/react-hooks-passing-thoughts)

I have completed up until the final stage. However, I cannot get the ‘thoughts’ to remove themselves after the set time has elapsed. The console is not showing up any errors and I haven’t found a solution on other posts.

Please see the code below, and let me know if you see anything that may be the issue!

App.js

import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import { AddThoughtForm } from './AddThoughtForm';
import { Thought } from './Thought';
import { generateId, getNewExpirationTime } from './utilities';

function App() {
  const [thoughts, setThoughts] = useState([
    {
      id: generateId(),
      text: 'This is a place for your passing thoughts.',
      expiresAt: getNewExpirationTime(),
    },
    {
      id: generateId(),
      text: "They'll be removed after 15 seconds.",
      expiresAt: getNewExpirationTime(),
    },
  ]);

  const addThought = (thought) => {
    setThoughts((thoughts) => [thought, ...thoughts]);
  };

  const removeThought = (thoughtIdToRemove) => {
    setThoughts((thoughts) => {
      thoughts.filter((thought) => {
        thought.id !== thoughtIdToRemove);
      });
    });
  };

  return (
    <div className="App">
      <header>
        <h1>Passing Thoughts</h1>
      </header>
      <main>
        <AddThoughtForm addThought={addThought}/>
        <ul className="thoughts">
          {thoughts.map((thought) => (
            <Thought 
              key={thought.id} 
              thought={thought} 
              removeThought={removeThought}
            />
          ))}
        </ul>
      </main>
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('app'));

Thought.js

import React, {useEffect} from 'react';

export function Thought(props) {
  const { thought, removeThought } = props;

  useEffect(() => {
    const timeRemaining = thought.expiresAt - Date.now();
    const timeout = setTimeout(() => {
      removeThought(thought.id);
    }, timeRemaining);
    return () => {
      clearTimeout(timeout);
    };
  }, [thought]);
  
  const handleRemoveClick = () => {
    removeThought(thought.id);
  };

  return (
    <li className="Thought">
      <button
        aria-label="Remove thought"
        className="remove-button"
        onClick={handleRemoveClick}
      >
        &times;
      </button>
      <div className="text">{thought.text}</div>
    </li>
  );
}

AddThoughtForm.js

import React, {useState} from 'react';
import { generateId, getNewExpirationTime } from './utilities';

export function AddThoughtForm(props) {

  const [text, setText] = useState('');

  const handleTextChange = (event) => {
    setText(event.target.value);
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    if (text.length > 0) {
      const thought = {
        id: generateId(),
        text: text,
        expiresAt: getNewExpirationTime(),
      };
      props.addThought(thought);
      setText('');
    };
  };

  return (
    <form 
      className="AddThoughtForm" 
      onSubmit={handleSubmit}>
      <input
        type="text"
        aria-label="What's on your mind?"
        placeholder="What's on your mind?"
        value={text}
        onChange={handleTextChange}
      />
      <input type="submit" value="Add" />
    </form>
  );
}

Utilities.js

export function getNewExpirationTime() {
  return Date.now() + 5 * 1000;
}

let nextId = 0;
export function generateId() {
  const result = nextId;
  nextId += 1;
  return result;
}

Many thanks,
Joshua

Hi Joshua,
I don’t know if that is all, but this function throws errors:

It is very helpful to do the react projects locally, because you get clear error messages and in this case the app would have failed to compile.
There is a syntax error and you don’t return anything. Either you write this:

thoughts.filter((thought) => {
        thought.id !== thoughtIdToRemove); // <-- superfluous parenthesis
});

in shorthand syntax:

 thoughts.filter(thought => thought.id !== thoughtIdToRemove);

or you add the return keyword.
Same here:

1 Like

Thank you very much!

All resolved now. I appreciate the explanation, I fixed the syntax error and experimented with adding the return keyword in both places and using the code on a single line. I’ll be sure to re-read over the documentation for arrow functions!

1 Like