skip to Main Content

I’m trying to create a modal which will be displayed in my index.js page. I do this by using useState to set its display state to true or false. However I want to access this useState from my BottomNavbar component so that when I click on a button in my component the modal is shown or later on hidden. However I cant seem to find how to access that useState from the other file. Any ideas?

Here is my index.js file where I load the modal :

// Import components
import Auth from '../components/Auth';
import Modal from '../components/Modal';
import React, { useState } from "react";

// Home page
export default function Home() {
  const [showModal, setShowModal] = useState(false);

  return (
    <main class="mt-2 flex flex-row justify-around items-center">
      <div class="mt-2 flex flex-col justify-center items-center basis-2/3">
        <section class="border-4 rounded-lg p-2 mb-2 bg-red-400 w-8/12">
          <h4 class="text-4xl font-bold text-slate-800">Welcome to Open Calendar!</h4>
          <p class="text-slate-800">Organize your day, week, or month with <strong>Open Calendar</strong>, <br></br> by signing up today or logging in.</p>
        </section>
        <Auth />
        <section class="border-4 rounded-lg p-2 mt-2 bg-red-400 w-8/12">
         <h4 class="text-4xl font-bold text-slate-800">How to use ?</h4>
         <p class="text-slate-800">Click on the + at the bottom of the screen to add an item to your <br></br> personalized calendar.</p>
        </section>
      </div>
      <div class="basis-1/3">
        <img class="h-96" src={'/calendar.png'} />
      </div>
      <Modal isVisible={showModal} />
    </main>
  );
}

Here is my BottomNavbar.js file where I want to change the modal display state from :

export default function BottomNavbar() {

  return (
    <nav class="fixed z-10 w-full h-16 max-w-lg -translate-x-1/2 bg-white border border-gray-200 rounded-full bottom-4 left-1/2">
      <div class="grid h-full max-w-lg grid-cols-3 mx-auto">
        <div class="inline-flex flex-col items-center justify-center px-5 rounded-full hover:bg-gray-50 group">

          {/* Change the showModal state from index.js here */}

          <button onClick={() => setShowModal(true)}>Calendar Settings</button>
        </div>
        <div class="flex items-center justify-center">
          <svg class="h-12 w-12 p-2 rounded-full bg-slate-500 hover:bg-blue-900" fill="white" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
            <path clip-rule="evenodd" fill-rule="evenodd" d="M12 3.75a.75.75 0 01.75.75v6.75h6.75a.75.75 0 010 1.5h-6.75v6.75a.75.75 0 01-1.5 0v-6.75H4.5a.75.75 0 010-1.5h6.75V4.5a.75.75 0 01.75-.75z"></path>
          </svg>
        </div>
        <div class="inline-flex flex-col items-center justify-center px-5 rounded-full hover:bg-gray-50 group">
          <button>Profile</button>
        </div>
      </div>
    </nav>
  );
}

And here is my Modal.js file where I create the modal :

import React from 'react'

export const Modal = ({ isVisible }) => {
  if (!isVisible) return null;
  
  return (
    <div class="fixed inset-0 bg-black bg-opacity-25 backdrop-blur-sm flex justify-center items-center">
      <div class="w-[600px] flex flex-col">
        <button class="place-self-end mb-2">
          <svg class="h-8 w-8 p-2 rounded-full bg-slate-500 hover:bg-blue-900" fill="white" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
            <path clip-rule="evenodd" fill-rule="evenodd" d="M5.47 5.47a.75.75 0 011.06 0L12 10.94l5.47-5.47a.75.75 0 111.06 1.06L13.06 12l5.47 5.47a.75.75 0 11-1.06 1.06L12 13.06l-5.47 5.47a.75.75 0 01-1.06-1.06L10.94 12 5.47 6.53a.75.75 0 010-1.06z"></path>
          </svg>
        </button>
        <div class="bg-white p-2 rounded-lg">Modal</div>
      </div>
    </div>
  )
}

export default Modal;

2

Answers


  1. you should create a function that make setShowModal to true and pass it to the components that changes the showModal state.

    const changeState=(value)=>{setShowModal(value);}
    
    <BottomNavbar changeState=changeState/>
    

    in BottomNavbar component:

    <button onClick={() => changeState(true)}>Calendar Settings</button>
    
    Login or Signup to reply.
  2. You should use lifting state up concept of React. You should declare the state on "least common ancestor component" of all the components that you want to use that state. For your example, let’s assume you want to use your BottomNavbar component in Home component. So, your Home component will look like this.

    <>
      <main>
        ...your existing code here
        <Modal isVisible={showModal} />
      </main>
      <BottomNavbar setShowModal={setShowModal}/>
    </>
    

    Your BottomNavbar component should accept setShowModal as a prop,

    export default function BottomNavbar({setShowModal}){
       ...your code here
    }
    

    If your state-consumer is far from least common ancestor component, you can avoid props drilling by using Context API or by restructuring component structure using component composition.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search