I have a navbar
component in which there is an input search bar. Currently I am taking the value of the search bar and navigate to the Results
component and access the input value useParams
.
I have the let [ result, setResult ] = useState([]);
in my Results
component because the results can change after the search is entered with buttons on the page. The problem is that I cannot set the initial result while defining the useState
because I am fetching from an API.
So every time I render, I first get an empty array and failed promise, after which I get the desired one. How to fix this? I need the search bar to be in the navbar.
This is the code. New to React.
const Navbar = () => { let navigate = useNavigate(); const handleKeyDown = (event) => { if (event.key === 'Enter') { let value = event.target.value; navigate(`/results/${value}`); } } return ( <nav className='navigation'> <div className='left-slot'> <button>runtime</button> </div> <div className="middle-slot"> <input className="after" placeholder="get runtimes" onKeyDown={handleKeyDown}> </input> </div> <div className='right-slot'> <button>How It Works</button> <button>Coming Soon</button> </div> </nav> ); }
const Results = () => { let { value } = useParams(); let [ result, setResult ] = useState(); useEffect(() => { fetchArrayByPage(value, page, option).then(res => setResult(res)) }, [value]) console.log(value); console.log(result); return (<div></div>) }
Advertisement
Answer
I’m not entirely sure why your code does not work, so I’ll provide three options.
Option 1 – If your problem is value
is undefined.
Change your useEffect
in Results
to this:
useEffect(() => { fetchArrayByPage(value && value.length ? value : '', page, option).then(res => setResult(res)) }, [value]);
Option 2 – If you need to pass props and Navbar
and Results
are not on separate routes.
Just pass value
as props from Navbar
to Results
.
Option 3 – Passing components without props.
Use the Context API. This enables you to share data across components without needing to manually pass props down from parent to child.
- Initialize variables in context.
- Create separate file containing context.
import React, { createContext } from 'react'; const NavbarContext = createContext(null); export default NavbarContext;
- Import said context to
App.js
orApp.tsx
if you’re using Typescript. - Declare variables and store them in an object for later reference.
const [value, setValue] = useState(''); ... const variables = { value, setValue, ..., };
- Wrap with Provider. Pass context variables to the Provider, enabling components to consume
variables
.
return ( <NavbarContext.Provider value={variables}> ... </NavbarContext.Provider> );
- Import and use all your variables in
Navbar
andResults
.
const { value, setValue, ... } = useContext(NavbarContext);