ReactJS 自定义钩子没有保持它的状态

时间:2021-01-06 12:58:38

标签: reactjs react-hooks

<块引用>

主要场景是我想要一个计时器来获取新通知,但有时我需要在我定义的间隔周期之外获取通知,所以我把它放在一个 useEffect 包装器中,并且我在一个状态中创建了一个状态customHook 以便我可以从其他组件更改它,并在我的 useEffect 钩子依赖项列表中使用该状态。现在我希望 Compo1 重新运行 useEffect 但它没有发生......

我有一个带有这个 package.json 的项目:

{
  "name": "---",
  "version": "1.2.0",
  "private": true,
  "dependencies": {
    "@babel/runtime": "^7.7.7",
    "@date-io/jalaali": "^1.3.11",
    "@material-ui/core": "^4.11.2",
    "@material-ui/icons": "^4.11.2",
    "@material-ui/lab": "^4.0.0-alpha.57",
    "@material-ui/pickers": "^3.2.10",
    "@material-ui/styles": "^4.11.2",
    "animate.css": "^3.7.2",
    "axios": "^0.21.1",
    "clipboard-copy": "^3.1.0",
    "clsx": "^1.1.1",
    "dotenv": "^8.2.0",
    "env-cmd": "^10.0.1",
    "formik": "^2.0.8",
    "i18next": "^17.3.1",
    "jss": "^10.0.0",
    "jss-rtl": "^0.2.3",
    "lodash": "^4.17.15",
    "material-table": "^1.54.1",
    "material-ui-popup-state": "^1.6.1",
    "md5": "^2.2.1",
    "moment": "^2.24.0",
    "moment-jalaali": "^0.9.2",
    "notistack": "^0.9.7",
    "num2persian": "^3.1.3",
    "query-string": "^6.9.0",
    "react": "^17.0.1",
    "react-circular-progressbar": "^2.0.3",
    "react-detect-offline": "^2.4.0",
    "react-dom": "^17.0.1",
    "react-file-icon": "^1.0.0",
    "react-helmet": "^6.1.0",
    "react-i18next": "^10.13.2",
    "react-image": "^2.2.1",
    "react-minimal-pie-chart": "^6.0.1",
    "react-moment": "^0.9.6",
    "react-redux": "^7.2.2",
    "react-router": "^5.2.0",
    "react-router-dom": "^5.2.0",
    "react-scripts": "^4.0.1",
    "react-slidedown": "^2.4.5",
    "react-step-wizard": "^5.3.0",
    "react-toastify": "^5.5.0",
    "redux": "^4.0.5",
    "styled-components": "^4.4.1",
    "url-parse": "^1.4.7",
    "yup": "^0.28.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "prop-types": "^15.7.2",
    "typescript": "4.1.3"
  },
  "resolutions": {
  }
}

我有两个组件和一个带有此内容的自定义钩子

我的自定义钩子:

export const useHeaderNotifUpdater = () => {
    const [signalUpate, dispatchUpdateNotifSignal]          = useState(true);
    console.log(signalUpate);
    return {signalUpate, dispatchUpdateNotifSignal};
};

组合 1:

import {connect} from "react-redux";
import withRouter from "react-router-dom/withRouter";

const Compo1 = ({history, balance, setBalance, setMobileVerifyStatus, userInfo}) => {
    const {signalUpate}                     = useHeaderNotifUpdater();
    const [notifs, setNotifs]               = useState(new Notifs({}));
    const [notifsLoading, setNotifsLoading] = useState(true);

    console.log('Compo1',signalUpate);
    useEffect(() => {

        let timeout = 0;

        const tick = () => {
            clearTimeout(timeout);

            api.notifs.getAllNotifis()
                .then(({data}) => {
                    setNotifs(new Notifs(data));
                })
                .catch(() => {
                })
                .finally(() => {
                    if (notifsLoading)
                        setNotifsLoading(false);
                    timeout = setTimeout(tick, 5000);
                })
        };
        tick();
        return () => {
            clearTimeout(timeout);
        };
        //eslint-disable-next-line
    }, [signalUpate]);

    return <div>{notifs?.length}</div>;

};

const mapStateToProps = state => ({
    balance          : state.auth.balance,
    isMobileNotVerify: state.auth.isMobileNotVerify,
    userInfo         : state.auth.userInfo,
});

const mapDispatchToProps = {
    logout,
    setBalance,
    setMobileVerifyStatus
};

export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Compo1));

组合 2:

const Compo2 = () => {
    const {dispatchUpdateNotifSignal} = useHeaderNotifUpdater();
    const handleUpdateNotifs=()=>{
        dispatchUpdateNotifSignal(prevState => !prevState);
    }
    return <button onClick={handleUpdateNotifs}>Click me!</>;
};
export default Compo2;
<块引用>

问题是状态在我的自定义钩子里面,是从外面改变的,但在 Compo1 中永远不会改变!这很奇怪!

1 个答案:

答案 0 :(得分:1)

每次调用自定义钩子 useHeaderNotifUpdater() 时,它都会创建一个新状态。您应该只在公共父组件上创建一种状态,或者使用上下文或管理状态库创建全局状态。