I want to sort an array of cards by name whenever I click on a control button located in another component. I´m using useContext. The sort method is not working when I use it like this. console.log("array",players.sort((a,b) => b.realName - a.realName)
enter code here
import { createContext, useContext, useEffect, useState } from "react";
import api from "./api/players"
const APIcontext = createContext();
export function Provider({children}){
const [players, setPlayers] = useState([]);
const [currentPlayer, setCurrentPlayer] = useState(null)
useEffect(() => {
const fetchPlayers = async () => {
try{
const response = await api.get('/players');
setPlayers(response.data)
}
catch(err){
if(err.response){
console.log(err.response.data)
}else{
console.log(`Error: ${err.message}`)
}
}
}
fetchPlayers()
},[])
const UpdateDetails = (player) => setCurrentPlayer(player)
const SortAsc = () => {
console.log("array",players.sort((a,b) => b.realName - a.realName))
}
return(
<APIcontext.Provider value={{players, currentPlayer,UpdateDetails, SortAsc}}>{children}</APIcontext.Provider>
)
}
export default APIcontext;
Controls Component. Here is the button that sorts the array.
import { createContext, useContext, useEffect, useState } from "react";
import api from "./api/players"
const APIcontext = createContext();
export function Provider({children}){
const [players, setPlayers] = useState([]);
const [currentPlayer, setCurrentPlayer] = useState(null)
useEffect(() => {
const fetchPlayers = async () => {
try{
const response = await api.get('/players');
setPlayers(response.data)
}
catch(err){
if(err.response){
console.log(err.response.data)
}else{
console.log(`Error: ${err.message}`)
}
}
}
fetchPlayers()
},[])
const UpdateDetails = (player) => setCurrentPlayer(player)
const SortAsc = () => {
console.log("array",players.sort((a,b) => b.realName - a.realName))
}
return(
<APIcontext.Provider value={{players, currentPlayer,UpdateDetails, SortAsc}}>{children}</APIcontext.Provider>
)
}
export default APIcontext;
card Component. This is the component I want to render the sorted cards
import React, { useEffect, useState, useContext } from "react";
import Card from "react-bootstrap/Card";
import APIcontext from "../context";
import Details from "./Details";
function Cards({}) {
const { players } = useContext(APIcontext);
console.log("players", players);
const { UpdateDetails} = useContext(APIcontext)
return (
<>
{players &&
players.map((player) => (
<Card
key={player.id}
className="mt-4 mx-2"
style={{
display: "flex",
width: "12rem",
height: "9rem",
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
}}
>
<Card.Body onClick={()=> UpdateDetails(player)}>
<Card.Title>{player.realName}</Card.Title>
<Card.Subtitle className="mb-2 text-muted">
{player.playerName}
</Card.Subtitle>
<Card.Text>{player.asset}</Card.Text>
</Card.Body>
</Card>
))}
</>
);
}
export default Cards;
I would appreciate any help.
CodePudding user response:
Your method would be right if it were to sort integer values. However, for this case, you require some additional code.
You first need to convert the strings to lowercase or uppercase, your choice and the compare them in one of 2 ways:
First -
objs.sort((a,b) =>
{
const aName = a.realName.toLowerCase(), bName = b.realName.toLowerCase();
return ((aName > bName) ? 1 : ((bName > aName) ? -1 : 0))
})
Second, much simpler:
objs.sort((a,b) => a.realName.toLowerCase().charCodeAt(0) - b.realName.toLowerCase().charCodeAt(0));
Basically, converts the character at position 0 of realName
to its corresponding ASCII value then compares which is bigger or smaller
CodePudding user response:
Try
players.sort((a,b)=>b.realName === a.realName ? 0 : a.realName > b.realName ? 1 : -1)