【问题标题】:Simple React counter not working, also can't console.log useState variables?简单的 React 计数器不起作用,console.log 也不能使用状态变量?
【发布时间】:2019-07-06 12:26:45
【问题描述】:

我对 React 还很陌生(一个月前才开始学习),我正在尝试在页面上显示一个简单的计数器,但它只会更新一次。另外,每当我console.log() useState 变量时,它们总是为空,但是由于我将它们添加到页面上的输出,我可以看到它们正在更新,但我仍然无法 console.log 值?是什么赋予了?我一定做错了什么,但我不知道为什么。

这是codesandbox 中“问题”的演示。

这是代码:

import React, { useState } from "react";

import "jqwidgets-scripts/jqwidgets/styles/jqx.base.css";
import JqxInput from "jqwidgets-scripts/jqwidgets-react-tsx/jqxinput";

const MyForm2: React.FC = () => {
  const [count, setCount] = useState(0);
  const [email, setEmail] = useState("");
  const [name, setName] = useState("");

  const onEmailChange = (e?: any) => {
    setCount(count + 1);
    setEmail(e.args.value);
    console.log('You typed: ' + e.args.value);
    console.log("name: " + name + ", email: " + email);
  };

  const onNameChange = (e?: any) => {
    setCount(count + 1);
    setName(e.args.value);
  };

  return (
    <div>
      Name:{" "}
      <JqxInput value={name} onChange={(e: any) => setName(e.args.value)} />
      Email: <JqxInput value={email} onChange={onEmailChange} />
      <p>Count: {count}</p>
      <p>email: {email}</p>
      <p>name: {name}</p>
    </div>
  );
};

export default MyForm2;

谢谢。我期待着找出我的重大错误:-)

【问题讨论】:

  • 关于无法使用console.log,我现在意识到这是因为它是一个功能组件。每次组件需要更新时都会调用该函数,因此每次都是新调用(与类不同;这也可以解释为什么 useState 变量实际上是常量,但似乎可以“一直”更新)。这就是我在 React.FC 中使用 console.log 的方式(但不是在我的 onWhateverChange 方法中): useEffect(() => console.log('count = ' + count));

标签: javascript reactjs typescript


【解决方案1】:

当下一个状态依赖于前一个状态时,您应该将函数更新器作为参数传递给setState。所以改成这样:

setCount((count) => count + 1)

【讨论】:

  • 这导致计数每次增加 2。我检查了我的控制台以确认该事件没有被调用两次(导致消息加倍)。如果我每次添加 0.5,它会按照我想要的方式工作,但我不明白为什么我不能只添加一个?
  • 实际上,事件 is 被调用了两次。在 Codesandbox 上打开控制台时,您看不到双倍消息,但关闭控制台后,您可以看到蓝色圆形圆圈中的数字每次递增两次。
【解决方案2】:

Javascript Closures、onNameChange 范围在 count 变量时关闭:

const MyForm2: React.FC = () => {
  const [count, setCount] = useState(0);
  const [email, setEmail] = useState('');
  const [name, setName] = useState('');

  const onEmailChange = (e?: any) => {
    setCount(prev => prev + 1);           // <-- no closure, use previous state
                                          // Render as expected.
    setEmail(e.args.value);
  };

  const onNameChange = (e?: any) => {
    setCount(count + 1);                  // <-- `count` always 0;
                                          // Will always redner the value '1'.
    setName(e.args.value);
  };

  return (
    <div>
      Name: <JqxInput value={name} onChange={onNameChange} />
      Email: <JqxInput value={email} onChange={onEmailChange} />
      <p>Count: {count}</p>
    </div>
  );
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-07
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    相关资源
    最近更新 更多