OnClick event results differently in form and image

Viewed 31

I have a navbar component with a search bar and the main page component. When an npm package name is inputted in the search bar it should render the main page component with the details of the package using api.npms.io.

App.jsx

function App() {
  const [input, setInput] = useState('react');

  return (
    <div className="App">
      <Navbar setInput={setInput} />
      <div className="sections">
        <Main input={input} />
      </div>
    </div>
  );
}

export default App;

navbar

function Navbar({ setInput }) {
  const inputRef = useRef();

  const submitHandler = () => {
    setInput(inputRef.current.value);
    inputRef.current.value = '';
  };

  return (
    <div className="Navbar" id="Navbar">
      <div className="logo">
        <img src={logo} alt="logo" />
      </div>
      <div className="line"></div>
      <form onSubmit={submitHandler}>
        <div className="search">
          <img src={search} alt="search" onClick={submitHandler} />
          <input
            placeholder={'Search for a NPM package'}
            name="name"
            type="text"
            ref={inputRef}
            id="name"            
          ></input>
        </div>
      </form>
    </div>
  );
}

export default Navbar;

Main.jsx

function Main({ input }) {
  const [packageInfo, setPackageInfo] = useState(null);
  const [loading, setLoading] = useState(true);

  const fetchPackageInfo = async (input) => {
    const response = await fetch(`https://api.npms.io/v2/package/${input}`);
    const data = await response.json();
    setPackageInfo(data);
    setLoading(false);
  };

  useEffect(() => {
    fetchPackageInfo(input);
  }, [input]);

  return (
    <div>
      {loading ? (
        <Loader />
      ) : (
        <div className="Main" id="Main">
          <div className="row">
            <Summary
              heading={packageInfo.collected.metadata.name}
              version={packageInfo.collected.metadata.version}
              description={packageInfo.collected.metadata.description}
              license={packageInfo.collected.metadata.license}
              npm={packageInfo.collected.metadata.links.npm}
              github={packageInfo.collected.metadata.links.homepage}
              downloads={Math.trunc(
                packageInfo.evaluation.popularity.downloadsCount
              ).toLocaleString()}
              keywords={packageInfo.collected.metadata.keywords.join(', ')}
            />
          </div>
        </div>
      )}
    </div>
  );
}

export default Main;

When I input the value in the search bar and then click on the image or the search icon, it gives me the expected output which is to render the details of the package but while the data is being fetched from the API it does not show the loader. The next problem is when I submit the inputted value it renders the details of the default package which is react and not the package name entered in the search bar.

Any help would be beneficial. Also, I am new to React and am not sure if I am managing state the right way.

1 Answers

I fixed the problem by adding setLoading(true) before fetching the API and also by adding e.preventDefault() in the submitHandler() function

Related