Javascript useState中的默认值未重新初始化
我有一个快餐店组件,它会显示一条祝酒词几秒钟,然后消失。我有一个Javascript useState中的默认值未重新初始化,javascript,reactjs,react-hooks,setstate,use-state,Javascript,Reactjs,React Hooks,Setstate,Use State,我有一个快餐店组件,它会显示一条祝酒词几秒钟,然后消失。我有一个应用程序组件,其中包含一个按钮,单击该按钮,我想控制快餐店组件。第一次单击时,快餐店显示良好,并在指定时间结束后消失。但是当我再次单击它时,快餐店不会出现。每次我都将显示状态初始化为true,但是快餐店没有出现。请告诉我哪里出了问题,以及如何纠正。下面是文件。我正在使用一个自定义挂钩来控制快餐店外观的行为 App.js import React, { useState } from "react"; import
应用程序组件
,其中包含一个按钮
,单击该按钮
,我想控制快餐店组件
。第一次单击时,快餐店
显示良好,并在指定时间结束后消失。但是当我再次单击它时,快餐店
不会出现。每次我都将显示状态
初始化为true,但是快餐店
没有出现。请告诉我哪里出了问题,以及如何纠正。下面是文件。我正在使用一个自定义挂钩来控制快餐店外观的行为
App.js
import React, { useState } from "react";
import { Snackbar } from "./Snackbar";
function App() {
const [display, setDisplay] = useState(false);
return (
<div>
<button onClick={() => setDisplay(true)}>Click me</button>
{display && <Snackbar message="hello" />}
</div>
);
}
export default App;
import React from "react";
import { useSnackbar } from "./useSnackbar";
const Snackbar = ({ message }) => {
const { showSnackbar } = useSnackbar();
return (
showSnackbar && (
<div>
<p>{message}</p>
</div>
)
);
};
export { Snackbar };
import { useState, useEffect } from 'react';
const useSnackbar = () => {
const [showSnackbar, setSnackbar] = useState(true);
const [snackbarMessage, setSnackbarMessage] = useState('');
useEffect(() => {
const timer = setTimeout(() => {
setSnackbar(false);
setSnackbarMessage('');
}, 3000);
return () => {
clearTimeout(timer);
};
}, [showSnackbar]);
return {
showSnackbar,
setSnackbar,
snackbarMessage,
setSnackbarMessage
};
};
export { useSnackbar };
确实,
useSnackbar
钩子对于showSnackbar
有一个默认值true
,并且在3秒钟后它确实会变为false
,但是App.js中的display
会保持true
,这意味着即使在超时之后
由于display
从未设置为false
,Snackbar
从未卸载,因此useSnackbar
的状态从未重新初始化
我的建议是改变useSnackbar
使用方式的结构
我会将useSnackbar
移动到App.js
并在那里设置snackbar打开状态
function App() {
const { showSnackbar, setSnackbar } = useSnackbar();
return (
<div>
<button onClick={() => setSnackbar(true)}>Click me</button>
{showSnackbar && <Snackbar message="hello" />}
</div>
);
}
const Snackbar=({message})=>(
{message}
);
有其他方法可以构造电子组件,但对于您的示例,这将是最简单的解决方案之一。您不需要在App.js中重置显示状态
解决方案
将重置状态回调函数传递给Snackbar
以传递给useSnackbar
挂钩
const useSnackbar = (onClose) => { // <-- callback function
const [showSnackbar, setSnackbar] = useState(true);
const [snackbarMessage, setSnackbarMessage] = useState('');
useEffect(() => {
const timer = setTimeout(() => {
setSnackbar(false);
setSnackbarMessage('');
onClose && onClose(); // <-- invoke when timer expired
}, 3000);
return () => {
clearTimeout(timer);
onClose && onClose(); // <-- edge case if component unmounts before expire
};
}, [onClose, showSnackbar]);
return {
showSnackbar,
setSnackbar,
snackbarMessage,
setSnackbarMessage
};
};
const Snackbar = ({ message, onClose }) => {
const { showSnackbar } = useSnackbar(onClose); // <-- pass callback to hook
return (
showSnackbar && (
<div>
<p>{message}</p>
</div>
)
);
};
export default function App() {
const [display, setDisplay] = useState(false);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<div>
<button onClick={() => setDisplay(true)}>Click me</button>
{display && <Snackbar message="hello" onClose={() => setDisplay(false)} />} // <-- pass reset callback
</div>
</div>
);
}
const useSnackbar=(onClose)=>{//{
常量计时器=设置超时(()=>{
设置nackbar(假);
设置nackbarmessage(“”);
onClose&&onClose();//{
清除超时(计时器);
onClose&&onClose();//{
const{showSnackbar}=useSnackbar(onClose);//单击我
{display&&setDisplay(false)}/>}//
const Snackbar = ({ message }) => (
<div>
<p>{message}</p>
</div>
);
const useSnackbar = (onClose) => { // <-- callback function
const [showSnackbar, setSnackbar] = useState(true);
const [snackbarMessage, setSnackbarMessage] = useState('');
useEffect(() => {
const timer = setTimeout(() => {
setSnackbar(false);
setSnackbarMessage('');
onClose && onClose(); // <-- invoke when timer expired
}, 3000);
return () => {
clearTimeout(timer);
onClose && onClose(); // <-- edge case if component unmounts before expire
};
}, [onClose, showSnackbar]);
return {
showSnackbar,
setSnackbar,
snackbarMessage,
setSnackbarMessage
};
};
const Snackbar = ({ message, onClose }) => {
const { showSnackbar } = useSnackbar(onClose); // <-- pass callback to hook
return (
showSnackbar && (
<div>
<p>{message}</p>
</div>
)
);
};
export default function App() {
const [display, setDisplay] = useState(false);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<div>
<button onClick={() => setDisplay(true)}>Click me</button>
{display && <Snackbar message="hello" onClose={() => setDisplay(false)} />} // <-- pass reset callback
</div>
</div>
);
}