3

I am working on a search bar in react which in another file will make a call to the unsplash-api, I have a search bar component and I am thinking of doing the api call in the main file or if other wise advised in another file in the src folder

So far I have setup a component and setup the initial hook but I dont know how to go forward

import React, { useState } from 'react';
import './SearchBar.css';

const SearchBar = () => {
  const [search, setSearch] = useState('');
  return (
    <form>
      <input className="Search" placeholder="Search Images" />
      <button type="submit" id="submit" className="search-button">
        <i className="icon">search</i>
      </button>
    </form>
  );
};
export default SearchBar;
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
tony_h
  • 95
  • 2
  • 10
  • 1
    [How to update parent's state in React?](https://stackoverflow.com/q/35537229/1218980) – Emile Bergeron Jul 29 '19 at 17:54
  • 3
    You should move the state up high enough so that any component that needs it can access it. Context API can be beneficial here. – go_diego Jul 29 '19 at 17:54
  • That isn't really what `useState` is for: it's a replacement for `this.state` from a class-based component. In the same way you can't access a component's state from the outside, you can't get at the hook. Move it up the chain and pass through props or context. Or use a separate data store. – Jared Smith Jul 29 '19 at 17:57
  • In my opinion Using the react `context API` works flawlessly so here is an implementaion using context API. using `useState` will still lead to prop drilling. You can check the answer to a simlar question here [Similar question answer](https://stackoverflow.com/questions/69870459/how-manage-global-state-using-context-api-in-react-js) – Felix Orinda Nov 08 '21 at 04:36

2 Answers2

0

See if that's what you're looking for. I replaced the form for a div to avoid submit behavior in the snippet. But the logic is the same. You'll need to do event.preventDefault on the submission event.

function mockSearchAPI(searchValue) {
  return new Promise((resolve,reject) => {
    setTimeout(() => resolve('Search results for: ' + searchValue), 2000);
  });
}

function App() {

  const [searchResults,setSearchResults] = React.useState('');
  const [loading, setLoading] = React.useState(false);

  function doSearch(searchValue) {
    setLoading(true);
    mockSearchAPI(searchValue)
    .then((results) => {
      setSearchResults(results);
      setLoading(false);
     });
  }


  return(
    <React.Fragment>
      <SearchBar
        doSearch={doSearch}
      />
      {loading &&
        <div>Loading...</div>
      }
      {searchResults && 
        <div>{searchResults}</div>
      }
    </React.Fragment>
  );
}

const SearchBar = (props) => {
  const [search, setSearch] = React.useState('');
  
  function onClick() {
    console.log(search);
    props.doSearch(search);
  }
  
  return (
    <div>
      <input 
        //className="Search" 
        placeholder="Search Images" 
        onChange={(event)=>setSearch(event.target.value)}
      />
      <button 
        //type="submit"
        //id="submit"
        //className="search-button"
        onClick={onClick}
      >
        <i className="icon">search</i>
      </button>
    </div>
  );
};

ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
cbdeveloper
  • 27,898
  • 37
  • 155
  • 336
0

From my understanding you should be able to pass the state in Hooks (from the search bar) to the parent component in these methods.

  1. Use Redux and create a global store with the required state variable. Then from the search component you will need to update the state variable in the Redux store, then load this state variable in the parent component.
  2. Create a state variable from the parent component and have it passed to the search component as a prop. Then from the search component, you will update this prop.

I am not not 100% sure if method 2 will work as expected but I am pretty sure method 1 will work.

Norman
  • 387
  • 2
  • 11