我已经阅读了一些有关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。
答案 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>
)
}