反应自定义挂钩不呈现
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);
有人可以向我解释这个错误吗?它到底告诉我什么,以便我完全理解这个错误,以及在这种情况下的原因是什么?
我该如何解决?
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);
};
我正在使用 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);
有人可以向我解释这个错误吗?它到底告诉我什么,以便我完全理解这个错误,以及在这种情况下的原因是什么?
我该如何解决?
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);
};