I am trying to delete an item (const removeItem) from a list using an onClick event in React. The state is managed with hooks. I know my way of deleting the item is not the right way yet (i'm putting the name to null), but this is not the issue.
After i set a user to null (i update the users object), i expect a render to happen (useEffect) but it does not. If i switch components and go back to this one, it works, but when clicking the X button, nothing happens in the view.
component Home:
import React, { Suspense, useState, useEffect } from "react";
const Home = props => {
const [users, setUsers] = useState(props.users);
console.log(users);
useEffect(() => {}, [users]);
const addItem = e => {
users.push(e);
console.log(e);
e.preventDefault();
};
const removeItem = item => {
users.forEach(user => {
if (user.id === item) {
user.name = null;
}
});
console.log(users);
setUsers(users);
};
return (
<div className="Home">
<form className="form" id="addUserForm">
<input
type="text"
className="input"
id="addUser"
placeholder="Add user"
/>
<button className="button" onClick={addItem}>
Add Item
</button>
</form>
<ul>
{users.map(item => {
return (
<>
<li key={item.id}>{item.name + " " + item.count}</li>
<button className="button" onClick={() => removeItem(item.id)}>
X
</button>
</>
);
})}
</ul>
</div>
);
};
export default Home;
How i get my users object:
import React from "react";
const LotsOfUsers =[...Array(100).keys()].map((item, key) => item = {
name : `User ${key}`,
id: key,
count: 0
})
export default LotsOfUsers;
main App:
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useRouteMatch,
useParams
} from "react-router-dom";
import Home from "./Home"
import CTX from './store'
import LotsOfUsers from "./LotsOfUsers";
export default function App() {
return (
<CTX.Provider value={{}}>
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
</ul>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/topics">
<Topics />
</Route>
<Route path="/">
<Home users={LotsOfUsers} text="hello world"/>
</Route>
</Switch>
</div>
</Router>
</CTX.Provider>
);
}
function About() {
return <h2>About</h2>;
}
function Topics() {
let match = useRouteMatch();
return (
<div>
<h2>Topics</h2>
<ul>
<li>
<Link to={`${match.url}/components`}>Components</Link>
</li>
<li>
<Link to={`${match.url}/props-v-state`}>
Props v. State
</Link>
</li>
</ul>
{/* The Topics page has its own <Switch> with more routes
that build on the /topics URL path. You can think of the
2nd <Route> here as an "index" page for all topics, or
the page that is shown when no topic is selected */}
<Switch>
<Route path={`${match.path}/:topicId`}>
<Topic />
</Route>
<Route path={match.path}>
<h3>Please select a topic.</h3>
</Route>
</Switch>
</div>
);
}
function Topic() {
let { topicId } = useParams();
return <h3>Requested topic ID: {topicId}</h3>;
}
useEffect(() => {}, users);
– leverglowhsetUsers
instead of the oldusers
either byfilter
or simply creating a copy ofusers
, modify the copy, and pass copy tosetUsers
– leverglowh