skip to Main Content

I am quite new to reactjs and am trying to render the data retrieved by an API call in reactjs. However, I am getting the following error:

"Objects are not valid as a React child (found: object with keys {key1, key2}). If you meant to render a collection of children, use an array instead."

This is my code:

function App() {
  const [returnedData, setReturnedData] = useState([]);

  const fetchData = async () => {
    const newData = await fetch("/api", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json",
      },
    }).then((res) => res.json());
    setReturnedData(newData);
  };

  fetchData();
  return (
    <>
      <div>
        {Object.keys(returnedData).map((item, index) => (
          <h2 key={index}>{returnedData[Number(item)]}</h2>
        ))}
      </div>
    </>
  );

}

export default App;

I would appreciate it if you let me know how to solve this problem! Basically, how I should render data without already knowing the keys? Because I only have access to keys after running the code.

The purpose of this program, is to retrieve data from a SQL server database. For this purpose, I am using express and mssql packages. This is the code that has to run on the server side:

const express = require('express');
const cors = require('cors');
const dbOperation = require('./dbFiles/dbOperation');

const API_PORT = process.env.PORT || 5000;

const app = express();
app.use(express.json());
app.use(express.urlencoded());

app.use(cors());

app.post('/api', async (req, res) => {
    console.log("Called!")
    const result = await dbOperation.getData();
    res.send(result);
});

app.listen(API_PORT, () => console.log(`Listening on port ${API_PORT}`));

And the following code is used to get the data from the database:

const config = require('./dbConfig');
const sql = require('mssql');

const getData = async() => {
    try{
        let pool = await sql.connect(config);
        let allData = await pool.request().query("SELECT * from Alerts");
        return allData;
    }
    catch(error){
        console.log(error);
    }
}
module.exports = {
    getData
}

2

Answers


  1. There is a problem with your code, it will cause an infinite loop。you cannot setState inside render. Modified the code like:

    If data is an Object like {key1: 1, key2:2}.

    function App() {
      const [returnedData, setReturnedData] = useState({});
    
      useEffect(() => {
    
        const fetchData = async () => {
          const newData = await fetch("/api", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
              Accept: "application/json",
            },
          }).then((res) => res.json())
          setReturnedData(newData)
        };
      
        fetchData();
      }, [])
    
      
      return (
        <>
          <div>
            {Object.keys(returnedData).map((item, index) => (
              <h2 key={item}>{returnedData[item]}</h2>
            ))}
          </div>
        </>
      );
    
    }
    
    export default App;
    

    If data is an Array like [1, 2], change return to:

    return (
        <>
          <div>
            {returnedData.map((item, index) => (
              // if item is an Object, you should use item.xxx to get anything you want. An Object child is not valid.
              <h2 key={index}>{item}</h2>
            ))}
          </div>
        </>
    );
    

    In this code, we use the useEffect hook to fetch the data from the server when the component is mounted. We also use the useState hook to keep track of the returned data.

    The return block uses the map method to iterate over the returned data and generate the corresponding HTML elements. We check the data type of each item to decide whether to render the item as a string or an object.

    I hope this helps!

    Login or Signup to reply.
  2. The reason for the above error is, You are trying to render an object instead of a primitive value, in this case, I guess you are trying to render a name or something which you think is a string value.
    returnedData[Number(item)] but apparently this return Object {}.
    This should be a string instead of an object. check your returnedData array value and ensure you are accessing the right value. and it should be a string (in this case).

      const result = await dbOperation.getData();
      res.send(result);
    

    ensure this result content data in the right format, it might be a JSON object. you might need to parse. JSON.parse(result).

    you can just console log your BE response and check what you are accessing using the key value. if the data structure is something like

    {item: {key: "", value: ""}
    

    you have to extract returnedData[Number(item)].value to render it correctly.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search