0

im new on react, coming from Angular. i would like to know how to reload Array List in React. i want to filter the contain of getVilles like in the script, in the reload from place it display the right value i expected, but in the JSX it doesnt reload. How to do it correctly please.

Here is my Array : Concert.js

export const Concert = [
    {
            id: 1,
            imgSource: "...",
            artistName: "Artist Name",
            tourName: "Tour Name",
            date: "Date and hour",
            place: "Aix-en-provence",
            categorie : "Rock",
            tarifs:{
                to : "de",
                at : "a"
            }  
    },
    {
        id: 2,
        imgSource: "...",
        artistName: "Artist Name 2",
        tourName: "Tour Name",
        date: "Date and hour",
        place: "Aix-en-provence",
        categorie : "Elektro",
        tarifs:{
            to : "de",
            at : "a"
        }  
    },
    {
        id: 3,
        imgSource: "...",
        artistName: "Artist Name 2",
        tourName: "Tour Name",
        date: "Date and hour",
        place: "Dunkerque",
        categorie : "Elektro",
        tarifs:{
            to : "de",
            at : "a"
        }  
    },
    {
        id: 4,
        imgSource: "...",
        artistName: "Artist Name 2",
        tourName: "Tour Name",
        date: "Date and hour",
        place: "Cannes",
        categorie : "Elektro",
        tarifs:{
            to : "de",
            at : "a"
        }  
    },
    {
        id: 5,
        imgSource: "...",
        artistName: "Artist Name 2",
        tourName: "Tour Name",
        date: "Date and hour",
        place: "Cannes",
        categorie : "Elektro",
        tarifs:{
            to : "de",
            at : "a"
        }  
    },
    {
        id: 6,
        imgSource: "...",
        artistName: "Artist Name 6",
        tourName: "Tour Name",
        date: "Date and hour",
        place: "Cannes",
        categorie : "Elektro",
        tarifs:{
            to : "de",
            at : "a"
        }  
    },
    
];

Here is the card component which display each data : concert.component.ts

import { Link} from 'react-router-dom';


function ConcertComponent(props) {
    //console.log("Ville filter = ", props.ville);
    return <div className="card" style={{ width: '18rem' }}>
                    {/* <img src="..." className="card-img-top" alt="..."/> */}
                    <div className="card-body">
                        <h5 className="card-title">{ props.concertData.artistName }</h5>
                        <p className="card-text">{ props.concertData.categorie } </p>
                        <p className="card-text">{ props.concertData.place } </p>
                    
                        <Link to="#" className="btn btn-primary">Reserver</Link>
                    </div>
                </div>
}
export default ConcertComponent;

And here is The Page which contain all data with filter : ProgrammationView.js

export const getVilles = ["Aix-en-provence","Bourges","Cannes", "Dunkerque", "Echirolles"];
export const getCat = ["Pop", "Rock", "Elektro","Rap / Hip-Hop", "Soul / Funk", "Classique", "Dub / Reggae", "World"];
export const sortBy = ["Dates Croissante", "Dates décroissante", "A-Z", "Z-A"];

let getConcert = Concert;

const reloadFromPlace = (ville) =>
{   
        getConcert = Concert.filter(concert => concert.place === ville);
        console.log("Ville change", getConcert);

}

const ProgrammationView = () => {

        return (
            <div className="App container">
                <h1> Programmation </h1>
                <div className="filter row">
                    <div className="col-md-12">
                        <div className="place row justify-content-md-left">
                            <div className="col-md-1 title">
                                <h5>Lieu</h5> 
                            </div>
                            <div className="col-md-8 btn-group" role="group">
                                <button type="button" className="btn btn-light">Tous</button>
                                {
                                    getVilles.map(ville => // !!!! Normally here it should display the filter values of getVilles, but it doesnt. Why ??
                                        <button type="button" key={ville} onClick={()=> {reloadFromPlace(ville)}} className="btn btn-light">{ville}</button>
                                    )
                                }
                            </div>
                        </div>
                    </div>
                   
                </div>
                <div className="concert">
                    <div className="row listData justify-content-md-center">
                    {
                        getConcert.map(item => 
                            <React.Fragment key={item.id}>
                                <ConcertComponent concertData={item} key={item.id}></ConcertComponent>
                            </React.Fragment>
                            )
                    }
                    </div>
                    
                </div>
            </div>
        );
}
export default ProgrammationView;
1
  • You need side effects to re-render Components. Commented Jan 23, 2021 at 20:10

1 Answer 1

1

To re-render the component on changes, you need a local state. You can also use the useEffect Hook, if the concerts are coming from the props. https://reactjs.org/docs/hooks-effect.html

Here is an example of the local state (useState) Hook: Consider your Button onClick Handler:

button type="button" key={ville} onClick={()=> {reloadFromPlace(ville)}} className="btn btn-light">{ville}</button>

// And your read Method should do following:
const reloadFromPlace = (ville) =>
{   
        getConcert = Concert.filter(concert => concert.place === ville);
        setConcert(getConcert); // This changes the local state, which will trigger re-render
        console.log("Ville change", concert);

}

It correctly calls the reloadFromPlace function. But to tell your component, that something changed, the component has a local state, which doesn't change automatically.

Use the useState Method to keep a local state parameter:

const [concert, setConcert] = React.useState(Concert.slice(0, Concert.length); //add the Concert Array as a local state parameter

Then, change your JSX to use the local state parameter concert:

<div className="concert">
  <div className="row listData justify-content-md-center">
    { concert.map(item =>
    <React.Fragment key={item.id}>
      <ConcertComponent concertData={item} key={item.id}></ConcertComponent>
    </React.Fragment>
    ) }
  </div>
</div>

The final function definition could looks like this:

export const getVilles = ["Aix-en-provence", "Bourges", "Cannes", "Dunkerque", "Echirolles"];
export const getCat = ["Pop", "Rock", "Elektro", "Rap / Hip-Hop", "Soul / Funk", "Classique", "Dub / Reggae", "World"];
export const sortBy = ["Dates Croissante", "Dates décroissante", "A-Z", "Z-A"];

let getConcert = Concert;

const ProgrammationView = () => {
    const [concert, setConcert] = React.useState(Concert.slice(0, Concert.length); //add the Concert Array as a local state parameter

    const reloadFromPlace = (ville) => {
        getConcert = Concert.filter(concert => concert.place === ville);
        setConcert(getConcert); // This changes the local state, which will trigger re-render
        console.log("Ville change", getConcert);
    }

    return (
        <div className="App container">
            <h1> Programmation </h1>
            <div className="filter row">
                <div className="col-md-12">
                    <div className="place row justify-content-md-left">
                        <div className="col-md-1 title">
                            <h5>Lieu</h5>
                        </div>
                        <div className="col-md-8 btn-group" role="group">
                            <button type="button" className="btn btn-light">Tous</button>
                            {
                                getVilles.map(ville => // !!!! Normally here it should display the filter values of getVilles, but it doesnt. Why ??
                                    <button type="button" key={ville} onClick={() => { reloadFromPlace(ville) }} className="btn btn-light">{ville}</button>
                                )
                            }
                        </div>
                    </div>
                </div>

            </div>
            <div className="concert">
                <div className="row listData justify-content-md-center">
                    {
                        concert.map(item =>
                            <React.Fragment key={item.id}>
                                <ConcertComponent concertData={item} key={item.id}></ConcertComponent>
                            </React.Fragment>
                        )
                    }
                </div>

            </div>
        </div>
    );
}
export default ProgrammationView;
Sign up to request clarification or add additional context in comments.

1 Comment

Here is a link to the State Hook Documentaiton: reactjs.org/docs/hooks-state.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.