React Hooks, как разделить состояние между двумя функциями - PullRequest
0 голосов
/ 12 марта 2020

Я пришел из 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;

Как бы я мог получить доступ к [mobileNavOpen, setMobileNavOpen] в Home () и MobileNav (). По сути, я хочу достичь домашнего компонента, где пользователи могут нажать кнопку, после чего открывается компонент MobileMenu, и еще одна кнопка, которую они могут использовать, чтобы снова закрыть меню.

Прямо сейчас, вторая строка сверху const [mobileNavOpen, setMobileNavOpen] = useState(false); приводит к Error: Invalid hook call. Hooks can only be called inside of the body of a function component., но куда бы я ее поместил?

Должна ли эта строка находиться в компоненте Home (), и все дочерние компоненты генерируют событие, чтобы показать или закрыть меню? Или мне нужна библиотека управления состоянием для чего-то такого простого? Что такое «Реагировать» способ сделать это?

Ответы [ 4 ]

1 голос
/ 12 марта 2020

, если ваш 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 <></>
}
1 голос
/ 12 марта 2020
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. передать функцию установщика состояния вашему дочернему компоненту
1 голос
/ 12 марта 2020

Простой способ - передать модификатор состояния дочернему компоненту. Для этого необходимо переместить хук внутри родительского компонента.

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;

Документы предоставляют лучшие рекомендации по управлению общим состоянием.

0 голосов
/ 12 марта 2020

Должна ли эта строка находиться в компоненте Home () и все дочерние компоненты генерируют событие, чтобы показать или закрыть меню?

Да. Затем передайте состояние MobileNavComponent

...