如何使用React钩子确定边栏是否应显示?

时间:2019-07-12 10:49:28

标签: reactjs react-hooks

我已经阅读了一些有关React Hooks的介绍,并希望制作一个带有标题组件中按钮的简单应用程序,该按钮确定主应用程序是否应显示侧边栏。该按钮在标题中设置了变量showSidebar,我想在我的主要组件中再次读取它。为简洁起见,删除了用于实际显示侧边栏的代码。

这是index.js

import React, { useState } from "react";
import ReactDOM from "react-dom";

import Header from "./header";
import "./styles.css";

function App() {
  const [showSidebar, setShowSidebar] = useState(true);

  return (
    <div className="App">
      <Header />
      <h1>Sidebar toggler</h1>

      <p>
        Should I show sidebar? <b>{showSidebar.toString()}</b>
      </p>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

这是header.js

import React, { useState } from "react";
export default function Header() {
  const [showSideBar, setShowSidebar] = useState(true);
  const toggleSidebar = () => setShowSidebar(!showSideBar);

  return (
    <header>
      Button in header toggles sidebar:
      <button onClick={() => toggleSidebar()}>
        Toggle sidebar (state: {showSideBar.toString()})
      </button>
    </header>
  );
}

我是React的新手,但不明白为什么index.js中的状态不会更新?我还用代码制作了CodeSandbox

4 个答案:

答案 0 :(得分:1)

useState是存储 local 状态的,为了进行比较,您可以认为它类似于类组件中的setState(尽管实际上它们不是{{3} }。因此,在setShowSidebar中设置App不会反映与在Header中设置的值相同,反之亦然。

如果Header只是在更改外部组件的状态,它看起来并不需要任何形式的本地状态,您可以传入事件处理程序,而任何相关状态Header都需要作为道具

index.js

function App() {
  const [showSidebar, setShowSidebar] = useState(true);
  const toggleSidebar = useCallback(() => setShowSidebar(value => !value));

  return (
    <div className="App">
      <Header onClick={toggleSidebar} showSideBar={showSidebar} />
      <h1>Sidebar toggler</h1>
      <p>
        Should I show sidebar? <b>{showSidebar.toString()}</b>
      </p>
    </div>
  );
}

header.js

export default function Header(props) {
  return (
    <header>
      Button in header toggles sidebar:
      <button onClick={props.onClick}>
        Toggle sidebar (state: {props.showSideBar.toString()})
      </button>
    </header>
  );
}

答案 1 :(得分:0)

您做错了什么是在Header中声明一个单独的状态,您不应该这样做,因为它与父级的状态无关。传递父状态和回调以更新父状态作为对标头的支持。将showSidebar作为道具传递到Header组件:

import React, { useState } from "react";
import ReactDOM from "react-dom";

import Header from "./header";
import "./styles.css";

function App() {
  const [showSidebar, setShowSidebar] = useState(true);

  return (
    <div className="App">
     // Pass prop here
      <Header 
        showSidebar={showSidebar} 
        toggleSidebar={()=>{setShowSidebar(!showSidebar)}}
         />
      <h1>Sidebar toggler</h1>

      <p>
        Should I show sidebar? <b>{showSidebar.toString()}</b>
      </p>
    </div>
  );
}

// and then in your Header,
export default function Header(props) {
  return (
    <header>
      Button in header toggles sidebar:
      <button onClick={props.toggleSideBar}>
        Toggle sidebar (state: {props.showSideBar.toString()})
      </button>
    </header>
  );
}

答案 2 :(得分:0)

您想将状态showSidebar保留在父组件中(需要读取状态),并将功能更改为标头组件(您需要更改showSidebar) >

要做的是将toggleSidebar移至index.js

const toggleSidebar = () => setShowSidebar(!showSideBar);

像这样将函数传递给Header组件

<Header toggleSidebar={toggleSidebar} />

现在像这样在Header组件的clickEvent上调用它

<button onClick={() => toggleSidebar()}>

请记住将prop包含在Header组件中

export default function Header({toggleSidebar}) {

答案 3 :(得分:0)

您应该在toggleSidebar中拥有App.js函数,并在toggleSidebar组件中传递showSidebar函数和Header状态作为道具。

App.js

function App() {
  const [showSidebar, setShowSidebar] = useState(true)
  const toggleSidebar = () => setShowSidebar(!showSidebar)

  return (
    <div className="App">
      <Header showSideBar={showSidebar} onClick={toggleSidebar} />
      <h1>Sidebar toggler</h1>

      <p>
        Should I show sidebar? <b>{showSidebar.toString()}</b>
      </p>
    </div>
  )
}

Header.js

import React from 'react'
export default function Header(props) {
  return (
    <header>
      Button in header toggles sidebar:
      <button onClick={props.onClick}>
        Toggle sidebar (state: {props.showSideBar.toString()})
      </button>
    </header>
  )
}

Demo