0

I was trying to retrieve data from database and display it in the browser on button click but I always receive this error (Uncaught Error: Objects are not valid as a React child (found: object with keys {studentId, firstName, surName, otherName, state, localGovt, phoneNumber, imgUrl}). If you meant to render a collection of children, use an array instead.). I was able to see the data when I use console.log, but failed in the DOM.

Here is the code on the frontend.

import Axios from "axios";
import { useState, useEffect } from "react";

const SearchUsers = () => {
  const [input, setInput] = useState("");
  const [studentResult, setStudentResult] = useState([]);

  const handleSearch = async () => {
    //const sanitizedInput = input.trim().toUpperCase();

    try {
      const { data } = await Axios.get("http://localhost:3500/students");
      const { result } = data; // this is an array
      console.log(result)//this works. it displays array of objects with the data from the db
        setStudentResult(result);
    } catch (error) {
      console.log(error);
    }
  };

  return (
    <>
      <div className="flex flex-col w-2/4 mx-auto my-20">
        <div>
          <input
            className="input w-full"
            type="text"
            name="search"
            placeholder="Search a Student"
            onChange={(e) => setInput(e.target.value)}
          />
        </div>
        <div className="flex justify-center mt-5">
          <button
            type="button"
            className="btn shadow shadow-gray-500"
            onClick={handleSearch}
          >
            Get All Students
          </button>
        </div>

        <div>
          {studentResult.map((item, index) => {
            return (
              <div key={index}>
                <p>{item.firstName}</p>
              </div>
            );
          })}
        </div>
      </div>
    </>
  );
};
export default SearchUsers;

Here is code on the backend. It's a controller function that retrieves all data from the database

const getAllStudents = (req, res) => {
  const selectAll = "SELECT * FROM students";

  studentDB.query(selectAll, (err, result) => {
    res.sendStatus(200).json({ result: result });
  });
};
8
  • use object here instead of array const [studentResult, setStudentResult] = useState([]); in useState([]) Commented Jan 25, 2023 at 9:06
  • If I use an object instead of an array I cannot iterate through it using Array.map() function as I was trying to do. And it was what the error message was complaining about. Or maybe I don't understand what you meant. Commented Jan 25, 2023 at 9:14
  • what was the result of studentResult? Commented Jan 25, 2023 at 9:16
  • The data retrieved from db was an array of objects with string keys and string values like [{studentId: "someId", firstName:"someName", lastName:"someName"}] etc... which I was trying to pass to studentResult and the iterate through it with Array.map() in the DOM Commented Jan 25, 2023 at 9:21
  • what was your expected output? Commented Jan 25, 2023 at 9:22

1 Answer 1

1

What's going wrong?

The problem arises when you:

  1. Initialize useState with an empty array, and
  2. Didn't define its type;

Then, the type of array will implicitly be assigned to never[], meaning that array should always be empty.

Therefore, mutating that array, including via setStudentResult(newArray), will always fail.

How to fix it

To solve this, we need to explicitly define the type of the empty array. For example:

const [studentResult, setStudentResult] = useState<{name: string, grade:number}[]>([]);

You should change the type declaration above based on the data structure of result.

Hope it helps. Cheers.

Sign up to request clarification or add additional context in comments.

Comments

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.