filtering out users in react
so im new to react and there is a book and a task given i need to filter out users by the upvotes the one user with most upvotes must be on the top but i have no idea how to do it also when i press on one user the state of upvote changes on all users can anyone help ? what am i doing wrong or am i doing everything wrong
import React from 'react';
import Nav from './Nav';
import './App.css';
import react,{Component} from'react'
const Items = [
{
img: "https://pbs.twimg.com/profile_images/1219033860991848448/UKWAPwfG_400x400.jpg",
header:"Netlify, our Conversion from Angular to React",
website:"netlify.com",
timeAuthor:"Submitted 9 hours ago by brianlammar",
},
{
img:"https://pbs.twimg.com/profile_images/1825094360/random_dude_400x400.jpg",
header:"React in patterns - List of design patterns ragaca",
website:"github.com",
timeAuthor:"Submitted 9 hours ago by magenta_placenta",
},
{
img:"https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/c8366146-25b7-49b3-a640-58439d2a2baa/d5gs9sv-0c98ab64-0f32-4c6d-90ed-39d38d2bf0ba.jpg/v1/fill/w_900,h_675,q_75,strp/random_dude_who_lives_near_me_by_misa_amane_17_d5gs9sv-fullview.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9Njc1IiwicGF0aCI6IlwvZlwvYzgzNjYxNDYtMjViNy00OWIzLWE2NDAtNTg0MzlkMmEyYmFhXC9kNWdzOXN2LTBjOThhYjY0LTBmMzItNGM2ZC05MGVkLTM5ZDM4ZDJiZjBiYS5qcGciLCJ3aWR0aCI6Ijw9OTAwIn1dXSwiYXVkIjpbInVybjpzZXJ2aWNlOmltYWdlLm9wZXJhdGlvbnMiXX0.YP5o5wapk-q4-6vpQIKaERchdyvNl8MOAs_cbG7ThfU",
header:"Redux vs Mobx vs Flux vs... Do you even...",
website:"goshakkk.name",
timeAuthor:"Submitted 8 hours ago by goshakk",
}
]
class App extends Component{
constructor(props){
super(props)
this.state= {
count:0
}
}
incremento(){
this.setState({
count:this.state.count + 1
})
}
decremento(){
this.setState({
count:this.state.count -1
})
}
render(){
return (
Items.map(item =>{
return (
<div>
<div className='section'>
<span className='Votes'>
<i onClick={() => this.incremento()} className="fas fa-arrow-up"></i>
<p>{this.state.count}</p>
<i onClick={() => this.decremento()} className="fas fa-arrow-down"></i>
</span>
<img src={item.img} />
<div className='Content'>
<h1 className='h'>{item.header}</h1>
<p>{item.website}</p>
<p>{item.timeAuthor}</p>
<span className='lil'>
<p className='red'>10 Comments</p>
<p>share</p>
<p>save</p>
<p>hide</p>
<p>report</p>
<p>pocket</p>
</span>
</div>
</div>
</div>
)
})
)
}
}
export default App;
It should look like this: https://codesandbox.io/s/gracious-glitter-jw34l?file=/src/App.js
import React { useState } from "react";
import Nav from './Nav';
import './App.css';
const Items = [
{
id: 1,
count: 0,
img:
"https://pbs.twimg.com/profile_images/1219033860991848448/UKWAPwfG_400x400.jpg",
header: "Netlify, our Conversion from Angular to React",
website: "netlify.com",
timeAuthor: "Submitted 9 hours ago by brianlammar"
},
{
id: 2,
count: 0,
img:
"https://pbs.twimg.com/profile_images/1825094360/random_dude_400x400.jpg",
header: "React in patterns - List of design patterns ragaca",
website: "github.com",
timeAuthor: "Submitted 9 hours ago by magenta_placenta"
},
{
id: 3,
count: 0,
img:
"https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/c8366146-25b7-49b3-a640-58439d2a2baa/d5gs9sv-0c98ab64-0f32-4c6d-90ed-39d38d2bf0ba.jpg/v1/fill/w_900,h_675,q_75,strp/random_dude_who_lives_near_me_by_misa_amane_17_d5gs9sv-fullview.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9Njc1IiwicGF0aCI6IlwvZlwvYzgzNjYxNDYtMjViNy00OWIzLWE2NDAtNTg0MzlkMmEyYmFhXC9kNWdzOXN2LTBjOThhYjY0LTBmMzItNGM2ZC05MGVkLTM5ZDM4ZDJiZjBiYS5qcGciLCJ3aWR0aCI6Ijw9OTAwIn1dXSwiYXVkIjpbInVybjpzZXJ2aWNlOmltYWdlLm9wZXJhdGlvbnMiXX0.YP5o5wapk-q4-6vpQIKaERchdyvNl8MOAs_cbG7ThfU",
header: "Redux vs Mobx vs Flux vs... Do you even...",
website: "goshakkk.name",
timeAuthor: "Submitted 8 hours ago by goshakk"
}
],
User = ({ counterChange, item }) => (
<div>
<div className="section">
<span className="Votes">
<i
onClick={() => {
counterChange(1);
}}
className="fas fa-arrow-up"
>
UP
</i>
<p>{item.count}</p>
<i
onClick={() => {
counterChange(-1);
}}
className="fas fa-arrow-down"
>
DOWN
</i>
</span>
<img src={item.img} />
<div className="Content">
<h1 className="h">{item.header}</h1>
<p>{item.website}</p>
<p>{item.timeAuthor}</p>
<span className="lil">
<p className="red">10 Comments</p>
</span>
</div>
</div>
</div>
);
const App = () => {
const [items, setItems] = useState(Items);
return (
<>
{items
.sort((a, b) => (a.count < b.count ? 1 : -1))
.map((item) => (
<User
item={item}
counterChange={(value) => {
const index = items.findIndex((d) => d.id === item.id),
a = [...items];
a[index].count = a[index].count + value;
setItems(a);
}}
/>
))}
;
</>
);
};
export default App;
The count is increasing for each user because, the count
state that you are maintaining is not specific to a user. It is a general, common counter.
What you could instead do is,
- Get rid of the
count
state. - Add a
users
state, which will be an array of users, with a count for each user. Something like:
this.state = Items.map(i => ({...i, count: 0}))
- Pass an id to the
incremento(id)
anddecremento(id)
methods. - This way now, you can update the count of only the user for which the up/down button was clicked inside your
incremento()
anddecremento()
methods - And in the render method, you can sort the
Items
array by thecount
field, and then render each user.
This way, you can have the count increased only for the clicked user, and users sorted by counts in descending order.