首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将状态从组件传递给父App.js (单击外部关闭导航栏)

如何将状态从组件传递给父App.js (单击外部关闭导航栏)
EN

Stack Overflow用户
提问于 2022-04-10 13:51:58
回答 2查看 44关注 0票数 0

当我单击关闭导航栏中的外部Navbar.js时,我想将一个状态从组件Navbar.js传递给App.js。我把州立道具从父母传给了一个孩子Navbar.js,当我点击Navbar外面的时候,它没有关闭

-Defined const [isSideMenuOpen, setIsSideMenuOpen] = useState(false); in App.js

将-Added道具传递给子组件<Navbar setIsSideMenuOpen={setIsSideMenuOpen} isSideMenuOpen={isSideMenuOpen} />

-Destructuring setIsSideMenuOpenisSideMenuOpen in Navbar.js (查看下面的代码)

App.js

代码语言:javascript
复制
import "../styles/globals.css";
import Navbar from "../comps/Navbar";
import { useState, useEffect, useRef } from "react";

let useClickOutside = (handler) => {
  let domNode = useRef();

  useEffect(() => {
    let maybeHandler = (event) => {
      if (!domNode.current?.contains(event.target)) {
        handler();
      }
    };

    document.addEventListener("mousedown", maybeHandler);

    return () => {
      document.removeEventListener("mousedown", maybeHandler);
    };
  });

  return domNode;
};

function MyApp({ Component, pageProps }) {
  const [isSideMenuOpen, setIsSideMenuOpen] = useState(false);
  let domNode = useClickOutside(() => {
    setIsSideMenuOpen(false);
  });
  return (
    <div className="relative">
      <Navbar
        setIsSideMenuOpen={setIsSideMenuOpen}
        isSideMenuOpen={isSideMenuOpen}
        domNode={domNode} // NEWLINE! passing to the SideMenu() function
      />
      <div ref={domNode}>
        <Component {...pageProps} />
      </div>
    </div>
  );
}

export default MyApp;

./components/Navbar.js

代码语言:javascript
复制
import { useState, useEffect, useRef } from "react";
import { HiMenuAlt1, HiOutlineX } from "react-icons/hi";

export default function Navbar({ isSideMenuOpen, setIsSideMenuOpen }) {
  const showSideMenu = () => {
    isSideMenuOpen ? setIsSideMenuOpen(false) : setIsSideMenuOpen(true);
  };

  return (
    <div className="absolute z-40 w-full h-8  text-cyan-600 flex flex-row justify-between items-center text-2xl ">
      <div className="brand-logo text-xl font-bold px-2 font-extrabold text-cyan-600">
        Trener
      </div>
      <ul className="md:flex hidden menu-list text-xl font-bold ">
        <li className="menu-list-item px-2">
          <a href="/">Strona główna</a>
        </li>
        <li className="menu-list-item px-2">
          <a href="#b">O mnie</a>
        </li>
        <li className="menu-list-item px-2">
          <a href="#c">Plany treningowe</a>
        </li>
      </ul>

      <button
        onClick={() => {
          showSideMenu();
        }}
        className="lg:hidden menu-button"
      >
        {isSideMenuOpen ? (
          <HiOutlineX className="w-8 h-8 px-2 bg-red-600" />
        ) : (
          <HiMenuAlt1 className="w-8 h-8 px-2" />
        )}
      </button>
      {isSideMenuOpen ? SideMenu() : ""}
    </div>
  );
}

// NEW LINE - Destructuring props domNode
function SideMenu({domNode}) {
  return (
    <div className="fixed z-20  w-1/2 sm:w-1/4 lg:hidden bg-gray-300 top-8 right-0 p-3" ref={domNode}>
//NEW LINE - assign ref={domNode}
      {/* sagsa */}
      <ul className="menu-list flex flex-col text-lg font-bold">
        <li className="menu-list-item py-2 hover:bg-white hover:text-blue-700">
          <a href="/">Strona główna</a>
        </li>
        <li className="menu-list-item py-2 hover:bg-white hover:text-blue-700">
          <a href="/about">O mnie</a>
        </li>
        <li className="menu-list-item py-2 hover:bg-white hover:text-blue-700">
          <a href="#c">Plany treningowe</a>
        </li>
      </ul>
    </div>
  );
}

更新:我添加了domNode={domNode} // NEWLINE!将道具传递给Navbar.js -> SideMenu()函数

代码语言:javascript
复制
// NEW LINE - Destructuring props domNode
function SideMenu({domNode}) {
  return (
    <div className="fixed z-20  w-1/2 sm:w-1/4 lg:hidden bg-gray-300 top-8 right-0 p-3" ref={domNode}>
//NEW LINE - assign ref={domNode} 
// (...)

发生错误:Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'domNode')function SideMenu({ domNode }) {

EN

回答 2

Stack Overflow用户

发布于 2022-04-10 14:01:36

这是因为您已经在子组件中定义了setIsSideMenuOpen,即Navbar.js

你能做什么定义

代码语言:javascript
复制
const [isSideMenuOpen, setIsSideMenuOpen] = useState(false)

在App.js中,然后将其作为道具传递给Navbar。这样,您就可以同时处理来自父和子的isSideMenuOpen。

票数 0
EN

Stack Overflow用户

发布于 2022-04-10 14:06:08

您不能将状态和它的setter函数从子组件传递到父组件,下面是您可以执行的方法

  1. 在App.js中定义状态及其设置器函数,然后将状态和设置器作为支持传递给Navbar.js,然后在这里使用它们作为道具。

  1. 使用State 概念,创建一个组合父组件并进行定义

const isSideMenuOpen,setIsSideMenuOpen =setIsSideMenuOpen

这里,并将其作为道具传递给组件的App.js和Navbar.js。

  1. 您可以简单地使用redux来避免状态传递问题.
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71817226

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档