bartc
bartc

Reputation: 123

Passing value from child to parent, after click event in child (which triggers function)

In <Nav/> component, "click event" on chevron <button>, triggers nextTitle(length) function in useNextTitle.js custom hook. This function sets the value of val, which is being returned by useNextTitle.js. How to pass that new val to App.js ?


Bigger picture: I want to change the display between <Dod /> and <Analogia /> (in App.js), after "click event" in <Nav /> (figured out val would be helpful for that, as a parameter in Conditional Statement).

Functionality I`m trying to achieve is visualized on the website I done with vanilla Java Script : link (the blue navigation, changes "main pages" with "titles" when chevron clicked)

App.js

import Nav from "./components/Nav";
import Dod from "./components/Dod";
import Analogia from "./components/Analogia";

function App() {

  return (

   <div className="App">

     <Nav />

     <Dod />

     <Analogia />


   </div>
     );
}

export default App

Nav.js

import useNextTitle from './useNextTitle';
import './Nav.css';

const Nav = () => {

  const navData = [
    {id: 0, text: "DOD"},
    {id: 1, text: "analogia"}
  ]

  const length = navData.length;

  const { val, nextTitle } = useNextTitle();

  return (
    <nav>
    <div>


        {/* titles */}
        <ul>
            <li key="li1">
                {navData.map((title, index) => {
                    return (
                        <div 
                            className={index === val ? "active" : "display-none"} key={title.id}>
                            {title.text}
                        </div>
                    )
                })}
            </li>
        </ul>

        {/* chevron button */}
        <div>
            <button onClick={() => nextTitle(length)}>
                <span className="material-icons">
                    chevron_right
                </span>
            </button>
        </div>
        
    </div>
    </nav>
  )
}
export default Nav

useNextTitle.js

import { useState } from 'react';

const useNextTitle = () => {

    const [val, setVal] = useState(0);

    const nextTitle = (length) => {
        setVal(val === length -1 ? 0 : val + 1 )
        console.log("hook vav = " + val)
    }
    return { val, nextTitle }
}

export default useNextTitle;

Upvotes: 2

Views: 94

Answers (1)

Drew Reese
Drew Reese

Reputation: 202721

Move the useNextTitle hook/state up to App and pass val and nextTitle down to Nav to toggle/update the state. Use val to conditionally render Dod and Analogia.

Example:

function App() {
  const { val, nextTitle } = useNextTitle();
  return (
    <div className="App">
      <Nav {...{ val, nextTitle }} />
      {val === 0 && <Dod />}
      {val === 1 && <Analogia />}
    </div>
  );
}

...

const Nav = ({ val, nextTitle }) => {
  const navData = [
    { id: 0, text: "DOD" },
    { id: 1, text: "analogia" }
  ];

  const length = navData.length;

  return (
    <nav>
      <div>
        {/* titles */}
        <ul>
          <li key="li1">
            {navData.map((title, index) => {
              return (
                <div
                  className={index === val ? "active" : "display-none"}
                  key={title.id}
                >
                  {title.text}
                </div>
              );
            })}
          </li>
        </ul>

        {/* chevron button */}
        <div>
          <button onClick={() => nextTitle(length)}>
            <span className="material-icons">chevron_right</span>
          </button>
        </div>
      </div>
    </nav>
  );
};

Edit passing-value-from-child-to-parent-after-click-event-in-child-which-triggers-f

Upvotes: 1

Related Questions