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

React中如何根据用户ID筛选待办事项列表中的任务

解决React中用户ID筛选失效的问题

核心问题是输入框返回的是字符串类型,而接口返回的userId是数字类型,使用===严格相等比较时类型不匹配,导致筛选条件永远不成立。

修复方案

有两种直接的解决思路:

1. 转换输入值为数字类型

在处理用户输入时,将字符串转为数字后再存入状态:

const onUserChange = (event) => {
  // 使用Number()转换,空值会变成0,可根据需求调整判断逻辑
  setUserId(Number(event.target.value))
}

同时给输入框添加type="number"属性,限制用户只能输入数字,提升体验:

<input type="number" onChange={onUserChange}/>

2. 筛选时统一类型比较

如果不想修改状态类型,可以在筛选阶段将两边转为同一类型再比较:

if(userId) {
  filteredTask = filteredTask.filter((item) => item.userId === Number(userId))
}

优化后的完整代码

推荐把所有筛选逻辑整合到useMemo中,避免重复计算,提升组件性能:

import React from "react"
import {useState, useMemo, useEffect} from "react"

function App() {
  const [tasks, setTasks] = useState([])
  const [completed, setCompleted] = useState(false)
  const [title, setTitle] = useState("")
  const [userId, setUserId] = useState(1)

  const onToggleFilter = () => {
    setCompleted(!completed)
  }

  const onTitleChange = (event) => {
    setTitle(event.target.value)
  }

  const onUserChange = (event) => {
    setUserId(Number(event.target.value))
  }

  // 所有筛选逻辑整合到useMemo,仅依赖项变化时重新计算
  const filteredTask = useMemo(() => {
    let result = tasks.filter(task => task.completed === completed)
    
    if(title) {
      result = result.filter(task => task.title.includes(title))
    }
    
    if(userId) {
      result = result.filter(item => item.userId === userId)
    }
    
    return result
  }, [tasks, completed, title, userId])

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/todos")
    .then(response => response.json())
    .then(todos => setTasks(todos))
  }, [])

  return(
    <div className="App">
      <h1>Task list</h1>
      <div>
        <button onClick={onToggleFilter}>
          {completed ? "Show tasks in work" : "Show completed tasks"}
        </button>
        <br/>
        <br/>
        <input placeholder="Filter by title" onChange={onTitleChange}/>
        <input type="number" placeholder="Filter by user ID" onChange={onUserChange}/>
        <br/>
        <br/>
        {filteredTask.map((task) => <div key={task.id}>{task.title}</div>)}
      </div>
    </div>
  )
}

export default App

补充说明

  • 若输入框为空时不想触发筛选,可在条件判断中增加userId !== 0的校验
  • task.title.includes(title)是ES6+的写法,比indexOf更直观,功能完全一致
  • 给输入框添加placeholder可以明确提示用户输入用途

内容的提问来源于stack exchange,提问作者Andrew Ivanov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 22:10:29