首页 > 解决方案 > TypeError:setState 不是 React 中的函数

问题描述

const { useState } = React;

//To display current time
const DateTime = () => {
  setInterval(getTime, 1000);

  let time = new Date().toLocaleTimeString();
  const [currentTime, updateTime] = useState(time);
  console.log(time);

  function getTime() {
    const newTime = new Date().toLocaleTimeString();
    updateTime(newTime);
  }
  return (
    <div className="date">
      <p>Time: {currentTime}</p>
      <button onClick={getTime}>Get Time</button>
    </div>
  );
}

const App = () => {

  return (
    <div className="container">
    <DateTime />
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById("root"));
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <title>React App</title>
</head>

<body>
    <div id="root"></div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
</body>

</html>

我是 React 的初学者。我正在尝试使用 useState 钩子在功能组件中显示当前时间,但我收到关于我的 setState 的以下错误(在我的情况下是 updateTime)

import React, { useState } from "react";
import "./Navbar.css";

//To display current time
function DateTime() {
  setInterval(getTime, 1000);

  let time = new Date().toLocaleTimeString();
  const [currentTime, updateTime] = useState(time);
  console.log(time);

  function getTime() {
    const newTime = new Date().toLocaleTimeString();
    updateTime(newTime);
  }
  return (
    <div className="date">
      <p>Time: {currentTime}</p>
      <button onClick={getTime}>Get Time</button>
    </div>
  );
}

export default DateTime;

Codesandbox 中的错误如下。我不明白这个错误的原因。有人可以帮忙吗?

TypeError
updateTime is not a function
getTime
/src/components/DateTime.jsx:14:4
  11 | 
  12 | function getTime() {
  13 |   const newTime = new Date().toLocaleTimeString();
> 14 |   updateTime(newTime);
     |  ^
  15 | }
  16 | return (
  17 |   <div className="date">

标签: javascriptreactjs

解决方案


您的代码片段的主要问题是您正在尝试使用没有钩子的 React v15。这就是为什么它说useState没有定义。

第二个问题是我在评论中描述的:您需要更改设置间隔计时器的方式。如果要在挂载时启动计时器,请在useEffect具有空依赖项数组的挂钩中执行此操作(并返回一个清除间隔的函数,该函数将在卸载时调用)。你现在拥有它的方式将在每次调用组件函数时启动一个新的计时器,也就是每次它需要渲染的时候。这将很快失去控制。

这是一个版本:

  1. React 的最新版本
  2. 使用设置定时器useEffect
  3. 一些进一步的说明,见评论

const { useState, useEffect } = React;

const DateTime = () => {
    let time = new Date().toLocaleTimeString();
    const [currentTime, updateTime] = useState(time);
    
    // Set up the interval timer using `useEffect`
    useEffect(() => {
        // Use a function local to this so it only gets created once
        // This isn't using `getTime` below because it would always
        // use the first one (and a linter would warn you that you
        // needed to add it as a dependency to `useEffect`, but we
        // know we don't want to).
        const timer = setInterval(() => {
            const newTime = new Date().toLocaleTimeString();
            updateTime(newTime);
        }, 1000);
        // Return a cleanup function...
        return () => {
            // ...that cancels the interval timer.
            clearInterval(timer);
        };
    }, []);

    // You don't need this if you don't need the button below
    function getTime() {
        const newTime = new Date().toLocaleTimeString();
        updateTime(newTime);
    }
  
    return (
        <div className="date">
            <p>Time: {currentTime}</p>
            {/* Do you really need this button since you have the timer? */}
            <button onClick={getTime}>Get Time</button>
        </div>
    );
}

const App = () => {
    return (
        <div className="container">
            <DateTime />
        </div>
    );
}

ReactDOM.render(<App />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>


推荐阅读