Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript useState中的默认值未重新初始化_Javascript_Reactjs_React Hooks_Setstate_Use State - Fatal编程技术网

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>
  );
}