反应自定义挂钩不呈现

React custom hook not rendering

我正在使用 Remix 使用 React 构建一个应用程序,fly.io 用于部署。我有一个自定义 React 钩子 useCountdown,它具有以下代码:

import { useEffect, useState } from 'react';

const useCountdown = (targetSeconds) => {
    const countDownSeconds = targetSeconds

    const [countDown, setCountDown] = useState(countDownSeconds);

    useEffect(() => {
        const interval = setInterval(() => {
            setCountDown(countDownSeconds);

            return () => clearInterval(interval);
        }, [countDownSeconds]);

        return getReturnValues(countDown);
    }, [])
};

const getReturnValues = (countDown) => {
    const seconds = Math.floor((countDown % (1000 * 60)) / 1000);

    return [seconds];
}

export { useCountdown }


DateTimeDisplay组件有如下代码,是hook的组件依赖:

import React from 'react';

const DateTimeDisplay = ({ value, type, isDanger }) => {
    return (
        <div className={isDanger ? 'countdown danger' : 'countdown'}>
            <p>{value}</p>
            <span>{type}</span>
        </div>
    );
};

export default DateTimeDisplay;

最后,我有一个具有以下代码的 CountdownTimer 组件:

import React from 'react';
import DateTimeDisplay from './DateTimeDisplay';
import ExpiredNotice from './ExpiredNotice'
import { useCountdown } from '../hooks/useCountdown';


const ShowCounter = ({ seconds }) => {
    return (
        <div className="show-counter">
                <DateTimeDisplay value={seconds} type={'seconds'} isDanger={false} />
        </div>
    );
};

const CountdownTimer = ({ targetSeconds }) => {
    const [seconds] = useCountdown(targetSeconds);

    if (seconds <= 0) {
        return <ExpiredNotice />;
    } else {
        return (
            <ShowCounter
                seconds={seconds}
            />
        );
    }
};

export default CountdownTimer;

尝试使用 useCountdown() 挂钩时,出现以下错误:

TypeError: useCountdown is not a function or its return value is not iterable
    at CountdownTimer (/Users/tduke/Desktop/dev/drawesome/app/components/CountdownTimer.jsx:17:23)
    at processChild (/Users/tduke/Desktop/dev/drawesome/node_modules/react-dom/cjs/react-dom-server.node.development.js:3353:14)
    at resolve (/Users/tduke/Desktop/dev/drawesome/node_modules/react-dom/cjs/react-dom-server.node.development.js:3270:5)
    at ReactDOMServerRenderer.render (/Users/tduke/Desktop/dev/drawesome/node_modules/react-dom/cjs/react-dom-server.node.development.js:3753:22)
    at ReactDOMServerRenderer.read (/Users/tduke/Desktop/dev/drawesome/node_modules/react-dom/cjs/react-dom-server.node.development.js:3690:29)
    at renderToString (/Users/tduke/Desktop/dev/drawesome/node_modules/react-dom/cjs/react-dom-server.node.development.js:4298:27)
    at handleRequest (/Users/tduke/Desktop/dev/drawesome/app/entry.server.jsx:10:16)
    at handleDocumentRequest (/Users/tduke/Desktop/dev/drawesome/node_modules/@remix-run/server-runtime/server.js:400:18)
    at requestHandler (/Users/tduke/Desktop/dev/drawesome/node_modules/@remix-run/server-runtime/server.js:49:18)
    at /Users/tduke/Desktop/dev/drawesome/node_modules/@remix-run/express/server.js:39:22

有问题的行:

    const [seconds] = useCountdown(targetSeconds);

  1. 有人可以向我解释这个错误吗?它到底告诉我什么,以便我完全理解这个错误,以及在这种情况下的原因是什么?

  2. 我该如何解决?

useCountdown 没有 return 语句,因此它隐含地 returning undefined。然后,当您尝试解构 undefined 时,您会收到该错误,因为数组解构仅适用于数组(或其他可迭代对象,这就是错误提到“可迭代”而不是数组的原因)

您确实在 useEffect 中放置了一个 return 语句,但是 return 在 useEffect 中添加一些东西是为了清理效果。它不会导致 useCountdown 到 return 任何事情。要解决此问题,请将 return 语句移至 useCountdown 的正文,并将效果清理移至效果中的 return:

const useCountdown = (targetSeconds) => {
    const countDownSeconds = targetSeconds

    const [countDown, setCountDown] = useState(countDownSeconds);

    useEffect(() => {
        const interval = setInterval(() => {
            setCountDown(countDownSeconds);
        }, [countDownSeconds]);

        return () => clearInterval(interval);
    }, [])

    return getReturnValues(countDown);
};