Search code examples
arraysreact-hooksreact-props

Why the data is not rendering on the page, while I am seing it on the console?


Hi everyone! I am building a search component for an application while facing this issue. The is problem that when I am fetching data I can see it in the in the console as you can see on the screenshoot, but I can't see something rending on the page.Can someone point where is the problem? Thank you.

enter image description here

Here are my codes:

App.js:

import React, { useState } from "react";

import Infos from "./components/CompanyInfo";
import Search from "./components/Search";
import axios from "axios";

function App() {
  const [state, setState] = useState({
    results: [],
  });

  const search = async (text) => {
    const results = await axios.get("https://cvrapi.dk/api", {
      params: { search: text, country: "dk" },
    });

    setState((prevState) => {
      return { ...prevState, results};
    });
  };

  return (
    <div className="App">
      <div className="container searchApp">
        <h2 className="title is-2 has-text-centered">
          Get CVR data into your own system
        </h2>
        <Search search={search} />
        <Infos results={state.results} />
      </div>
    </div>
  );
}

export default App;

Search:

import React, { useState } from "react";

function Search({ search }) {
  const [searchText, setSearchText] = useState("");

  const handleOnChange = (e) => {
    const text = e.target.value;
    setSearchText(text);
  };

  const handleEnterKeyPressed = (e) => {
    if (e.key === "Enter") {
      search(searchText);
    }
  };

  return (
    <div>
      <div className="control">
        <input
          className="input"
          onChange={handleOnChange}
          onKeyPress={handleEnterKeyPressed}
          type="text"
          value={searchText}
          placeholder="Company CVR"
        />
      </div>
    </div>
  );
}

export default Search;

CompanyInfo:

import React from "react";

function CompanyInfos({ results }) {
  let data = [];
  if (results.data) {
    data = results.data.Search || [];
  }
  console.log(data);
  return (
    <div className="result">
      {data.map((value, index) => (
        <ul>
          <li key={index}>Company CVR {value.vat}</li>
          <li>Address: {value.address}</li>
        </ul>
      ))}
    </div>
  );
}

export default CompanyInfo;

Solution

  • The problem is your data structures. You are calling data.map. But data is not an array, right? It looks like an object to be. I'm not seeing a property Search on the JSON either. Usually a search operation returns an array of results but here it seems to return just one match.

    You want a component that renders a single company's info:

    function CompanyInfo({ company }) {
      console.log(company);
      return (
        <div className="result">
          <h3>{company.name}</h3>
            <ul>
              <li key={company.vat}>Company CVR {company.vat}</li>
              <li>Address: {company.address}</li>
            </ul>
        </div>
      );
    }
    

    Your App stores a single result which is either a company info object or undefined. It should only render the CompanyInfo if we actually have a company and not undefined.

    function App() {
      const [result, setResult] = useState();
    
      const search = async (text) => {
        const response = await axios.get("https://cvrapi.dk/api", {
          params: { search: text, country: "dk" }
        });
    
        setResult(response.data);
      };
    
      return (
        <div className="App">
          <div className="container searchApp">
            <h2 className="title is-2 has-text-centered">
              Get CVR data into your own system
            </h2>
            <Search search={search} />
            {result && <CompanyInfo company={result} />}
          </div>
        </div>
      );
    }
    

    Code Sandbox Link