So I have the Project basically working but it has a bug.
The project is supposed to delete chat components containing text (or thoughts) after a set time.
The thoughts are objects with a {id, text, expiresIn} keys.
The bug: All components are deleted after setTimeout.
expected behavior Each component should set its own timer and delete its self afters expiresIn time.
I do not have access to regular debuging because CC uses a virtual browser that does not have access to react components. If no one can spot the bug, I will create this on my local machine but id rather not.
I watched the solution video and the guy never lets the timer delete multiple thoughts… I dont know if he did that on purpose but I was not able to see if this bug was duplicated in his code.
Here is my code I guess. Otherwise can you tell me if the app is supposed to behave like this?
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((prev) => [thought, ...prev]);
}
const removeThought = (thoughtIdToRemove) => {
const filteredThoughts = thoughts.filter(thought => thought.id !== thoughtIdToRemove);
setThoughts(filteredThoughts);
}
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'));
addthoughtform.js
import React, { useState } from 'react';
import { generateId, getNewExpirationTime } from './utilities';
export function AddThoughtForm({ addThought }) {
const [text, setText] = useState('');
const handleTectChange = (e) => {
setText(e.target.value);
}
const handleSubmit = (e) => {
e.preventDefault();
if (text) {
const thought = {
id: generateId(),
text,
expiresAt: getNewExpirationTime()
}
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={handleTectChange}
/>
<input type="submit" value="Add" />
</form>
);
}
thought
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}
>
×
</button>
<div className="text">{thought.text}</div>
</li>
);
}