Passing Thoughts Project - Unexpected Behavior

Hello. I was working on the Passing Thoughts project and I am having issues after implementing the final step (13). I’ve also watched the accompanying video, but the person who recorded it only showed the app deleting the first two thoughts after 15 seconds - my app also does that but the issue lies when trying to add a new thought to the list (which is the whole point of the app). When I hit the submit button with some text in it, it seems that the thought gets added and then immediately deleted afterwards. Consequently, I am unable to add any new thoughts to the list. If I use alert instead of removeThought, an alert is displayed every time I add a new thought, which is triggering useEffect.

Here’s the code:
Thought.js

import React, { useEffect } from "react";

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

  const handleRemoveClick = () => {
    removeThought(thought.id);
  };

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


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

AddThought.js

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

export function AddThoughtForm(props) {
  const [text, setText] = useState("");
  function handleTextChange(event) {
    setText(event.target.value);
  }
  function handleSubmit(event) {
    event.preventDefault();
    //create new thought object
    if (text.length > 0) {
      const thought = {
      id: generateId(),
      text: text,
      expirestAt: getNewExpirationTime(),
    };
    props.addThought(thought); 
    setText("");
    }
  }

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

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";

export default 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(),
    },
  ]);

  function addThought(thought) {
    setThoughts((prevThoughts) => [thought, ...prevThoughts]);
  }

  function removeThought(thoughtId) {
    setThoughts((thoughts) => {
     return thoughts.filter(thought => thought.id !== thoughtId ); 
    });
  }

  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>
  );
}

utilities.js

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

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

In your AddThought.js file, you wrote     expirestAt     instead of     expiresAt

// You wrote:
expirestAt: getNewExpirationTime(),

// It should be:
expiresAt: getNewExpirationTime(),

Thank you very much, I had not noticed that at all. It’s working as expected now.

1 Like