簡體   English   中英

React Hooks,如何在兩個函數之間共享狀態

[英]React Hooks, how to share state between two functions

我來自 Vue 背景,我很難理解如何在 HTML 分成多個部分時有條件地顯示某些內容。

假設我有以下結構:

import React, { useState } from "react";
const [mobileNavOpen, setMobileNavOpen] = useState(false);

function Home() {
  return (
    <div>
      <button
        onClick={(): void => setMobileNavOpen(true)}
        type="button"
        className="btn"
      >
        X
      </button>
      {mobileNavOpen && <MobileNav />}
    </div>
  );
}

function MobileNav() {
  return (
    <div>
      <button
        onClick={(): void => setMobileNavOpen(false)}
        type="button"
        className="btn"
      >
        X
      </button>
    </div>
  );
}

export default Home;

我如何才能在 Home() 和 MobileNav() 中訪問 [mobileNavOpen, setMobileNavOpen]。 基本上我想要實現的是一個 Home 組件,用戶可以按下一個按鈕,在這個按鈕上 MobileMenu 組件打開,另一個按鈕可以用來再次關閉菜單。

現在,從頂部開始的第二行const [mobileNavOpen, setMobileNavOpen] = useState(false); 導致Error: Invalid hook call. Hooks can only be called inside of the body of a function component. Error: Invalid hook call. Hooks can only be called inside of the body of a function component. 但我會把它放在哪里?

該行是否應該在 Home() 組件中並且所有子組件都發出一個事件來顯示或關閉菜單? 或者我需要一個狀態管理庫來做這么簡單的事情嗎? 什么是“反應”方式來做到這一點?

import React, { useState } from "react";

function Home() {
  const [mobileNavOpen, setMobileNavOpen] = useState(false);
  return (
    <div>
      <button
        onClick={() => setMobileNavOpen(true)}
        type="button"
        className="btn"
      >
        X
      </button>
      {mobileNavOpen && <MobileNav setMobileNavOpen={setMobileNavOpen} />}
    </div>
  );
}

function MobileNav({setMobileNavOpen}) {
  return (
    <div>
      <button
        onClick={() => setMobileNavOpen(false)}
        type="button"
        className="btn"
      >
        X
      </button>
    </div>
  );
}

export default Home;
  1. 您必須將 useState 掛鈎移動到組件主體
  2. 將狀態設置器函數傳遞給您的子組件

一種簡單的方法是將狀態修飾符向下傳遞給子組件。 為此,需要將鈎子移動到父組件內。

import React, { useState } from "react";


function Home() {
  const [mobileNavOpen, setMobileNavOpen] = useState(false);
  return (
    <div>
      <button
        onClick={(): void => setMobileNavOpen(true)}
        type="button"
        className="btn"
      >
        X
      </button>
      {mobileNavOpen && <MobileNav setMobileNavOpen={setMobileNavOpen} />}
    </div>
  );
}

function MobileNav(setMobileNavOpen) {
  return (
    <div>
      <button
        onClick={(): void => setMobileNavOpen(false)}
        type="button"
        className="btn"
      >
        X
      </button>
    </div>
  );
}

export default Home;

或者,您可以稍微抽象一下,以便您的子組件僅定義所需的內容:

import React, { useState } from "react";

function Home() {
  const [mobileNavOpen, setMobileNavOpen] = useState(false);
  return (
    <div>
      <button
        onClick={(): void => setMobileNavOpen(true)}
        type="button"
        className="btn"
      >
        X
      </button>
      {mobileNavOpen && <MobileNav onClose={() => setMobileNavOpen(false)} />}
    </div>
  );
}

function MobileNav(onClose) {
  return (
    <div>
      <button
        onClick={(): void => onClose()}
        type="button"
        className="btn"
      >
        X
      </button>
    </div>
  );
}

export default Home;

這些文檔提供了一些管理共享狀態的最佳實踐。

如果您的Home() Component呈現MobileNav() Component您應該將const [mobileNavOpen, setMobileNavOpen] = useState(false)放入Home()例如:

const Home = () => {
   const [mobileNavOpen, setMobileNavOpen] = useState(false)

   return ( 
   <>
    ...
    <MobileNav 
      handleMobileNav={mobileNavOpen}
    />
    ...
   </>)
}

const MobileNav = ({ handleMobileNav }) => {

   return <></>
}

該行是否應該在 Home() 組件中並且所有子組件都發出一個事件來顯示或關閉菜單?

是的。 然后將狀態傳遞給 MobileNavComponent

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM