Home > other >  React loop data from array in render
React loop data from array in render

Time:10-23

For some reason, I can't get .map() to render the data. I tried running the function directly in render and called it from render and nothing happened.

function Contracts(props) {
    const [isLoaded, setLoaded] = useState(true);
    const [error, setError] = useState(null);
    const [equipment, setEquipment] = useState([]);




    useEffect(() => {
        const getContracts = async () => {
            let snapshot = await db.getAllContracts();
            setTimeout(10000);
            if (snapshot) {
                console.log(snapshot);
                setError(null);
                setLoaded(true);
                snapshot.forEach((item, i) => {
                    console.log(item[1]);
                    equipment.push({
                        value: item, date: item.Dato, status: item.Status,
                        start: item.StartLocation, end: item.EndLocation,
                        col: item.Collateral, reward: item.Reward

                    });
                })
                console.log(equipment);

            } else {
                setLoaded(false);
            }
        }
        getContracts();

    }, [])

    const handleClick = (e) => {
        let target = e.target;
        let selectedEquipmentIndex = target.parentElement.getAttribute("dataset-id");
        this.setState({
            selectedEquipment: selectedEquipmentIndex
        });
    }

    const renderItems = () => {
        const data = equipment;
        console.log(data);
        const listItems = data.map(
            (element) => {
                console.log(element);
                return (
                    <id className="row" key={element} dataset-id={element} onClick={handleClick}>
                        <p className="date">{element.date.toString()}</p>
                        <p className="status">{element.status}</p>
                        <p className="start">{element.start}</p>
                        <p className="end">{element.end}</p>
                        <p className="col">{element.col}</p>
                        <p className="reward">{element.reward}</p>
                    </id>
                )
            }
        )
        return (
            <div>
                {listItems}
            </div>
        )
    }



    if (error) {
        return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
        return <div>Loading...</div>;
    } else {
        return (
            <article id="header">
                <article id="content">
                    <section >
                        <div classname="header"><h1></h1></div>
                        <div className="titleArea">
                            <div className="eqnavn"><h1>Date: </h1></div>
                            <div className="eqstatus"><h1>Status: </h1></div>
                            <div className="eqstart"><h1>Start: </h1></div>
                            <div className="eqend"><h1>End: </h1></div>
                            <div className="eqcol"><h1>Collateral: </h1></div>
                            <div className="eqreward"><h1>Reward: </h1></div>
                        </div>
                        {renderItems}

                    </section>
                </article>
            </article>
        )
    }
}

export default Contracts;

And I do get data from my database:

    [{…}]
0: 
col: "270000"
date: 1666454928600
end: "asdas"
reward: 49705
start: "asdasd"
status: "Not Taken"
value: {EndLocation: 'asdas', Size: 'Max 40T Space Safe', StartLocation: 'asdasd', Collateral: '270000', Username: 'Saphyron', …}

I hope someone can help me cause I'm getting stuck. Tried following some of the guides here but most is 5 years old and does not work sadly.

CodePudding user response:

You have to use the functions you've declared

{renderItems()}

instead of

{renderItems}

CodePudding user response:

If you want to update the data of equipment state, you have to call the setEquipment function. ( Do not update directly.)

useEffect(() => {
    const getContracts = async () => {
        let snapshot = await db.getAllContracts();
        setTimeout(10000);
        if (snapshot) {
            console.log(snapshot);
            const _equipment = [];    // <- here
            setError(null);
            setLoaded(true);
            snapshot.forEach((item, i) => {
                console.log(item[1]);
                _equipment.push({    // <- here
                    value: item, date: item.Dato, status: item.Status,
                    start: item.StartLocation, end: item.EndLocation,
                    col: item.Collateral, reward: item.Reward
                });
            })
            console.log(equipment);
            setEquipment(_equipment);    // <- here
        } else {
            setLoaded(false);
        }
    }
    getContracts();
}, []);

CodePudding user response:

You can use the map method instead of forEach here to create an array and update state accordingly as

const eqData = snapshot.map((item, i) => {
    equipment.push({
        value: item, date: item.Dato, status: item.Status,
        start: item.StartLocation, end: item.EndLocation,
        col: item.Collateral, reward: item.Reward

    });
})
setEquipment(eqData)

CodePudding user response:

You are trying to push data in equipment. But you can not modify state like this. States are not mutable . So you have to update your state with setState function. I am just rewrite the problematic part.

snapshot.forEach((item, i) => {
     console.log(item[1]);
     const newItem = {
          value: item, date: item.Dato, status: item.Status,
          start: item.StartLocation, end: item.EndLocation,
          col: item.Collateral, reward: item.Reward

     };

     setEquipment([...equipment, newItem])
 })
  • Related