skip to Main Content

How do I reset the Textfield in my <Search/> Component when I click the Logo in my <Header /> Component?

The <Search/> Component is already entangled with another Component through Callbacks and props.
I’ve tried custom Events, creating a higher Level State and passing the Event up through a Callback and then down again through a prop. This led to glitches and infinite rerenders or Invalid Hook Calls.

Whats the proper and best way to Pass this "Clear Event" to the <Search/> Component without running into those issues?

2

Answers


  1. I’d use useContext for handling the state of a small app.

    Here’s a working example

    const AppContext = React.createContext({
      search: "",
      setSearch: () => { console.error("setSearch called outside of app context") }
    })
    
    function App() {
      const [search, setSearch] = React.useState("")
      const appContext = {search, setSearch}
      return <AppContext.Provider value={appContext}>
        <Logo />
        <Search />
      </AppContext.Provider>
    }
    
    function Logo() {
      const { setSearch } = React.useContext(AppContext)
      return <a href="#" onClick={() => setSearch("")}>🚀</a>
    }
    
    function Search() {
      const { search, setSearch } = React.useContext(AppContext)
      return <input value={search} onChange={e => setSearch(e.currentTarget.value)} placeholder="search..." />
    }
    
    ReactDOM.createRoot(document.querySelector("#app")).render(<App />)
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <div id="app"></div>
    Login or Signup to reply.
  2. The Context API is how you get shared variables / functions between components.

    You can put the value of the search bar into a context to allow other components to modify it.

    Stackblitz: https://stackblitz.com/edit/stackblitz-starters-jxsehh?file=src%2Findex.tsx

    Snippet:

    const SearchCtx = React.createContext(null);
    
    const SearchCtxProvider = ({ children }) => {
      const searchTextState = React.useState('');
      return (
        <SearchCtx.Provider value={searchTextState}>{children}</SearchCtx.Provider>
      );
    };
    
    function Header() {
      const [searchText, setSearchText] = React.useContext(SearchCtx);
      return (
        <div>
          <h2>Header</h2>
          <button onClick={() => setSearchText('')}>RESET</button>
        </div>
      );
    }
    
    function Search() {
      const [searchText, setSearchText] = React.useContext(SearchCtx);
      return (
        <div>
          <h2>Search</h2>
          <input
            value={searchText}
            onChange={(e) => setSearchText(e.target.value)}
          />
        </div>
      );
    }
    
    function App() {
      return (
        <SearchCtxProvider>
          <Header />
          <Search />
        </SearchCtxProvider>
      );
    }
    
    const rootElement = document.getElementById('root');
    const root = ReactDOM.createRoot(rootElement);
    root.render(<App />);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
    <div id="root"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search