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.jsorApp.tsxif 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
NavbarandResults.
const { value, setValue, ... } = useContext(NavbarContext);