You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复React组件(使用useCallback钩子)中无数字输入时生成空白'NaN'项的问题

如何修复React组件(使用useCallback钩子)中无数字输入时生成空白'NaN'项的问题

我来帮你解决这个问题!首先咱们先分析一下为什么会出现NaN,然后一步步修复它~

首先,你的代码里有两个核心问题导致了NaN的出现:

  1. 输入框为空时,parseInt(e.target.value)会返回NaN,让Parent组件的number状态变成NaN,最终getItems返回的数组全是NaN;
  2. Child组件里有个小bug:useEffect中直接把props.getItems(这是一个函数)赋值给了items,而没有调用这个函数获取数组!

接下来咱们一步步修复:

步骤1:修复Child组件的函数调用错误

在Child组件的useEffect里,你需要调用props.getItems()来获取数组,而不是直接把函数本身存到items里。如果不调用函数,items会被设置成一个函数,后续map的时候会直接报错,这也是当前代码的隐藏问题~

修改后的Child组件useEffect部分:

useEffect(() => {
  setItems(props.getItems()); // 这里要调用函数,而不是传函数本身
  console.log('Updating List items')
}, [props.getItems])

步骤2:处理输入框的空值,避免number变成NaN

当输入框为空时,parseInt("")会返回NaN,这会让number状态变成NaN,进而导致生成的数组项全是NaN。我们可以在输入处理时给空值设置默认逻辑,这里提供两种方案供你选择:

方案A:空值时设为0(保持数组始终有3项)

如果你希望输入框为空时仍显示3个数字项,可以把空值默认设为0:
修改Parent组件的输入框onChange事件:

<input 
  type="number" 
  value={number} 
  onChange={e => {
    const inputValue = e.target.value;
    // 若输入为空,设为0;否则转成数字
    setMyNumber(inputValue ? parseInt(inputValue, 10) : 0);
  }} 
/>

方案B:空值时数组为空(不显示任何项)

如果你希望输入框为空时隐藏整个列表,可以把number设为null,然后在getItems里判断:
首先修改Parent的输入框onChange和value:

<input 
  type="number" 
  value={number || ''} // 空值时输入框显示为空
  onChange={e => {
    const inputValue = e.target.value;
    setMyNumber(inputValue ? parseInt(inputValue, 10) : null);
  }} 
/>

然后修改getItems函数:

const getItems = useCallback(() => {
  // 如果number是null,返回空数组;否则返回数字数组
  if (number === null) return [];
  return [number, number + 1, number + 2];
}, [number])

步骤3:额外的安全过滤(可选,双重保险)

为了彻底避免NaN出现在列表中,你可以在生成数组时过滤掉无效的数字,比如在Parent的getItems里:

const getItems = useCallback(() => {
  return [number, number + 1, number + 2].filter(item => !isNaN(item));
}, [number])

这样即使number不小心变成了NaN,过滤后数组会是空的,不会渲染出NaN项。

最终修复后的完整代码参考

ParentComp.jsx

import React , {useCallback, useState} from 'react'
import Childlist from './Childlist'

function ParentComp() {
  const [number, setMyNumber] = useState(1)
  const [dark, setTheme] = useState(false)

  const getItems = useCallback(() => {
    if (number === null) return [];
    return [number, number + 1, number + 2].filter(item => !isNaN(item));
  }, [number])

  const theme = {
    backgroundColor: dark? '#333': '#FFF',
    color: dark ? '#FFF' : '#333'
  }

  return (
    <div style={theme}>
      <input 
        type="number" 
        value={number || ''} 
        onChange={e => {
          const inputValue = e.target.value;
          setMyNumber(inputValue ? parseInt(inputValue, 10) : null);
        }} 
      />
      <button onClick={() => setTheme(prevDark => !prevDark)}> Toggle Theme </button>
      <Childlist getItems={getItems}/>
    </div>
  )
}

export default ParentComp

Childlist.jsx

import React, { useEffect, useState } from 'react'

function Childlist(props) {
  const [items, setItems] = useState([])

  useEffect(() => {
    setItems(props.getItems()); // 修复:调用函数获取数组
    console.log('Updating List items')
  }, [props.getItems])

  return items.map((each_item) => <div key={each_item}>{each_item}</div>)
}

export default Childlist

这样修改后,不管输入框是否为空,都不会再出现NaN项了~ 你可以根据自己的需求选择方案A或方案B。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 09:39:30