Share state React Hooks

Asked

Viewed 905 times

2

I’m having trouble sharing states between components using React Hooks. Can someone give me a help?

import React, { useState } from 'react'
import Nav from './Nav'


export default function Header(){

    const [open, setOpen] = useState(false);

    return(
        <header className="header">
            <div className="container">
                <Nav/>

                <div className="hamburger" id="hamburger-6" onClick={() => setOpen(!open)} className={open ? "is-active": ""}>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                </div>
            </div> 
        </header>
    );
}

I need to share the state open with the Nav component

import React, { useState, useEffect } from 'react'

export default function Nav(){
    const [open, setOpen] = useState(false);

    return(
        <nav className={open ? "header__nav active": "header__nav"}>
            <Link to="/" className="header__nav--link" onClick={() => setOpen(!open)} >Início</Link>
            <Link to="/sobre" className="header__nav--link" onClick={() => setOpen(!open)} >Sobre</Link>
            <Link to="/habilidades" className="header__nav--link" onClick={() => setOpen(!open)} >Habilidades</Link>
            <Link to="/projetos" className="header__nav--link">Projetos</Link>
            <Link to="/contato" className="header__nav--link">Contato</Link>
        </nav>
    );
}

3 answers

1


When the parent component is rendered, the child component is also rendered by default. You can use a logic not to update, but anyway, it makes sense to update when a prop change, which is what I will give as an example.

  1. Send the current status to Nav (open).
  2. Send a function that the Nav can execute indicating that you must open or close your menu (change the value of open)

When this function is called inside the Nav, the Header will update the state, rendering itself and the Nav with the new value of open.

Header

export default function Header(){
    const [open, setOpen] = useState(false);

    return(
        <header className="header">
            <div className="container">
                <Nav open={open} onClick={() => setOpen(!open}/>

                <div className="hamburger" id="hamburger-6" onClick={() => setOpen(!open)} className={open ? "is-active": ""}>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                </div>
            </div> 
        </header>
    );
}

Nav

export default function Nav({ open, onClick }){

    return(
        <nav className={open ? "header__nav active": "header__nav"}>
            <Link to="/" className="header__nav--link" onClick={() => onClick()} >Início</Link>
            <Link to="/sobre" className="header__nav--link" onClick={() => onClick()} >Sobre</Link>
            <Link to="/habilidades" className="header__nav--link" onClick={() => onClick()} >Habilidades</Link>
            <Link to="/projetos" className="header__nav--link">Projetos</Link>
            <Link to="/contato" className="header__nav--link">Contato</Link>
        </nav>
    );
}

Name the functions and names as it makes sense for your component, I left just a simple example of how it can be done.

  • 1

    Rafael ball show, I managed to reach a solution using your example, thank you very much :D

0

You’re looking to make one Prop Drilling which is basically pass props for their children and so on, example:

function Children({open}) {
  return (<div>{open ? "Aberto": "Fechado"}</div>)
}
function Father() {
  const [open, setOpen] = React.useState(false);
  const handleToggleOpen = () => setOpen(!open);
  return (
    <div>      
      <button onClick={handleToggleOpen}>
        {open ? "Aberto": "Fechado"}
      </button>
      <br /><br />
      <Children open={open} />
    </div>
  )
}
ReactDOM.render( <Father/> , 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"></div>

that is, by props can pass state from one component to the other. Depending on the situation it is best to use Redux or ContextApi that retrieve variables that can be shared on any component.

  • 1

    Thanks for your example Virgilio, I knew I could pass the state using Redux, but because it is a simple project I did not think it would be interesting to use it. But I’ll take a look at Contextapi, Vlw :D

-1

You’ve tried to pass that way?

<Nav props={open}/>

There you get so:

    function Nav({props}) {
    const [open, setOpen] = useState(props);
    ...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.