简体   繁体   中英

why useState is not updating data?

I am very new to react and after taking a course, I just wanted to do a project in react that I already did in Vue earlier just to practice React. But my useState is not updating the data that I want to list out.

The data from api is an array of Objects. End goal is to make a data table. So to be dynamic, I took the keys of the first object to take the column names. I used DataTable from 'react-data-table-component' for the data table. That didn't work. Now just to debug I thought to list out the column names but that didn't work either but it console logs.

I know this is something very basic and have searched lot of help in the internet and tried to solve who faced similar issue from lot of portals but nothing helped so far. Where am I doing wrong?

import React, { useState, useEffect, Component } from 'react'; 
import axios from 'axios'


const tableData = () => {
    const [tableData, setTableData] = useState([]);
    const [columns, setColumns] = useState([])

    useEffect(() => {
        axios.get('http://localhost:4000/')
            .then((res) => {
                if (res.status === 200) {
                    if (res.data === 0) {
                        console.log("Something is wrong !!!");
                    } else {
                        const data = res.data['rows']
                        const columns = Object.keys(data[0])
                        console.log(columns)
                        setTableData(data)
                        setColumns(columns)
                    }
                }
            }).catch(error => {
                console.log(error)
            })
    }, [])

    return (
        <div>
            <ul>
            {columns.map((columnName, index) => {
                const {name} = columnName;
                return (
                        <li key={index}>{ name }</li>
                       )
            })}
            </ul>
        </div>
    ) 
} 

in react state, set state works on references. sometime we need to change the state to the same reference that we changed the value of it. so instead put the same reference as an argument, we need to set a copy of it, because if we will set to the same state that already in the state, react can not see any different so it will not render again.

in your example, you didn't use the same reference for data, but for columns you used the same name of the state and the new columns.

example:

let referenceName = 'John';

const [name, setName] = useState(referenceName);

referenceName = 'Johnny'

setName(...referenceName )

I want to set the name of the state, but if i will NOT use the '...', react will not see any difference because i use the same reference.. so I need to put a copy od the refence for set a new reference.

  1. check the shape of response data here I simpliplified the useEffect by call that function out side
    import React, { useState, useEffect, Component } from "react";
    import axios from "axios";
    
    const tableData = () => {
      const [tableData, setTableData] = useState([]);
      const [columns, setColumns] = useState([]);
    
      const fetchDetails = () => {
        axios
          .get("http://localhost:4000/")
          .then((res) => {
            const data = res.data["rows"];
            const columns = Object.keys(data[0]);
            console.log(columns);
            setTableData(data);
            setColumns(columns);
          })
          .catch((error) => {
            //dont need to check the status if any occurs it will come to this catch block
            console.log(error.message);
          });
      };
    
      useEffect(() => {
        fetchDetails();
      }, [columns]);
    
      return (
        <div>
          <ul>
            {columns.map((columnName, index) => {
              const { name } = columnName;
              return <li key={index}>{name}</li>;
            })}
          </ul>
        </div>
      );
    };

can you try this block of code

 const [tableData, setTableData] = useState([]);
    const [columns, setColumns] = useState([])
    const [status , setStatus] = useState("idle")

  const fetchData = async()=>{
    try{
      setStatus("loading")
    const getFetch = await fetch('http://localhost:4000/')
    const convertToJson = await getData.json()
    const data = convertToJson.data['rows']
                        const getColumns = Object.keys(data[0])
                        console.log(getColumns)
                        setTableData(data)
                        setColumns(getColumns)
                        setStatus("success")
}catch(er){
  console.log("something wrong")
  setStatus("error")
}   
}
  React.useEffect(()=>{
   fetchData()
},[])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM