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
相关产品推荐
相关产品推荐

