如何通过关联ID将users.json的username匹配到subscription.json表格中显示
问题原因
你当前的写法存在两个核心问题导致username无法正常展示:
- 初始
users状态设置为[{}],且两个接口是异步加载的,在users数据未返回时就渲染表格,执行find匹配会得到空对象或undefined,读取username会报错 - 未处理
users.id和subscription.user_id的类型差异,比如一个是数字类型一个是字符串类型,全等===会匹配失败
修复后的完整代码
import React, {useEffect, useState} from 'react' import '../UserList/userlist.css' const Suscriber = () => { // 搜索初始值修正为空字符串,原写法类型错误 const [search, setSearch] = useState(""); const [data,setData]=useState([]); const [order, setorder] = useState("ASC"); // users初始值改为空数组 const [users,setUsers] = useState([]) useEffect(()=>{ fetch('data/users.json').then((res)=>res.json()).then((data)=>{ setUsers(data) }) },[]) const getData=()=>{ fetch('./data/subscriptions.json' ,{ headers : { 'Content-Type': 'application/json', 'Accept': 'application/json' } } ) .then(function(response){ console.log(response) return response.json(); }) .then(function(myJson) { console.log(myJson); setData(myJson) }); } useEffect(()=>{ getData() },[]) const sorting = (col) => { if (order === "ASC") { const sorted = [...data].sort((a,b)=> a[col].toString().toLocaleLowerCase() > b[col].toString().toLocaleLowerCase() ? 1 : -1 ); setData(sorted); setorder("DSC"); } if (order === "DSC") { const sorted = [...data].sort((a,b)=> a[col].toString().toLocaleLowerCase() < b[col].toString().toLocaleLowerCase() ? 1 : -1 ); setData(sorted); setorder("ASC"); } } return ( <div className="main"> <div className="search_option"> <h1 className="table-head">Subscribed User Data List</h1> <div className="input-icons"> <i className="fa fa-search icon" aria-hidden="true"></i> <input type="search" className="input-field" placeholder="Search......." onChange={(event) => { setSearch(event.target.value); }} /> </div> </div> <table> <thead> <tr> <th scope="col" onClick={()=>sorting("id")}>ID <i className="fas fa-sort sortings"></i></th> <th scope="col" onClick={()=>sorting("user_id")}>User ID <i className="fas fa-sort sortings"></i></th> <th scope="col">Username <i className="fas fa-sort sortings"></i></th> <th scope="col" onClick={()=>sorting("package")}>Package <i className="fas fa-sort sortings"></i></th> <th scope="col" onClick={()=>sorting("expires_on")}>Expire on <i className="fas fa-sort sortings"></i></th> </tr> </thead> <tbody> {data.filter((val) => { // 匹配用户,将username也纳入搜索范围 const matchUser = users.find(uid => Number(uid.id) === Number(val.user_id)) const username = matchUser?.username || '' if (search === ""){ return val } else if ( val.id.toString().toLocaleLowerCase().includes(search.toString().toLocaleLowerCase()) || val.package.toLocaleLowerCase().includes(search.toString().toLocaleLowerCase()) || username.toLocaleLowerCase().includes(search.toString().toLocaleLowerCase()) ){ return val } return false; }).map((val, key) => { // 匹配时统一转为数字避免类型差异匹配失败 const user = users.find(uid => Number(uid.id) === Number(val.user_id)); return <tr key={key}> <td data-label="ID">{val.id}</td> <td data-label="User ID">{val.user_id}</td> {/* 匹配不到时显示-避免报错 */} <td data-label="Username">{user?.username || '-'}</td> <td data-label="Package">{val.package}</td> <td data-label="Expire on">{val.expires_on}</td> </tr> })} </tbody> </table> </div> ) } export default Suscriber
核心修改点说明
- 修正了
search状态初始值类型错误,原来设置为数组不符合输入框值的类型要求 users初始值改为空数组,避免初始渲染时匹配到空对象读取属性报错- 匹配用户id时统一转为数字类型,避免类型不一致导致全等匹配失败
- 读取
username时增加可选链和兜底值,匹配不到用户时显示-不会导致页面崩溃 - 搜索逻辑新增username字段的匹配,支持通过用户名搜索订阅记录
- 修正了所有
class属性为className,符合React语法规范
内容的提问来源于stack exchange,提问作者Rakesh Shrestha
相关产品推荐
相关产品推荐

