Skip to content
Advertisement

How to get value from one component to another page/component without navigation?

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.

  1. 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 or App.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>
);
  1. Import and use all your variables in Navbar and Results.
const { value, setValue, ... } = useContext(NavbarContext);
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement