I´m trying to update the Detail component data whenever I select a card component. I´m using useContext hook but I´m stuck at this point and I don´t know how to do this. Could anybody please help?.
context.js
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 = () =>{
}
return(
<APIcontext.Provider value={{players, currentPlayer,UpdateDetails}}>{children}</APIcontext.Provider>
)
}
export default APIcontext;
This is the Detail Component where I want to display the data, whenever a card is selected on click.
Details.jsx
import React from "react";
import Button from "react-bootstrap/Button";
import Card from "react-bootstrap/Card";
import {useContext} from "react";
import APIcontext from "../context";
function Details() {
const {players} = useContext(APIcontext)
return (
<Card style={{width:"80%", marginRight:"20px"}}>
<Card.Header className="text-center"><h1>Details</h1>
</Card.Header>
<Card.Body className="px-5">
<h4>{players.realName}</h4>
<h4>{players.realName}</h4>
<h4>{players.assets}</h4>
<Button variant="primary">Go somewhere</Button>
</Card.Body>
</Card>
);
}
export default Details;
This is the Card component that displays the data from the players. By clicking on one of them the Details component should be updated.
Card Component
[enter code here
import React, { useEffect, useState, useContext } from "react";
import Card from "react-bootstrap/Card";
import APIcontext from "../context";
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}>
<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;][2]
App.js
import "./App.css";
import "bootstrap/dist/css/bootstrap.min.css";
import Card from "./components/Card";
import Details from "./components/Details";
import { Container, Row, Col } from "react-bootstrap";
import Controls from "./components/Controls";
import { useEffect, useState } from "react";
import { Provider } from "./context";
function App() {
return (
<div className="App">
<Provider>
<Container className="p-3 d-flex flex-row justify-content-between">
<Container className="p-5 d-flex flex-row mb-4 bg-light rounded-3">
<Details />
<Controls />
</Container>
</Container>
<Container className=" mr-5 mb-4 bg-light rounded-3 " style={{width:"65%", float:"left", marginLeft:"10%"}}>
<Container className="d-flex flex-row flex-justify-content-center flex-wrap mr-5 mb-4 bg-light rounded-3" >
<Card className="mr-2"/>
</Container>
</Container>
</Provider>
</div>
);
}
export default App;
Context implementation is easy, you only need to understand its flow and how to update the root values.
You have done everything right, and I believe all that is left is for you to update the Details
component on click of the Card
component. Here's how you could go about it.
Card
component, where you've handled the onClick
event:<Card.Body onClick={UpdateDetails}>
, change it to: <Card.Body onClick={() => UpdateDetails(player)}>
Details
component.context
file, in the UpdateDetails
method, collect the argument passed while calling the function and set the currentPlayer accordingly like this:const UpdateDetails = (player) => setCurrentPlayer(player)
Here, the context will get updated and wherever you use the currentPlayer
value will receive the new data.currentPlayer
state inside Details
file, import it along with players
state:const {players, currentPlayer} = useContext(ApiContext)
currentPlayer.name
or any other key from the player object.Hope this helps. Please accept this answer if it does! Thank you!