使用 React.js 合并数组元素的属性
介绍
当您使用来自服务器的数据更新 UI 时,您通常需要通过将一些外部属性合并到数组来修改前端收到的 JSON 响应。这些属性可能是将数据映射到您的状态并使用该状态创建受控组件所必需的。例如,如果您的服务器返回用户列表,并且您需要在每个用户旁边添加一个复选框作为受控组件,则需要向数组的每个元素附加一个附加属性,以跟踪所选用户。
本指南介绍如何使用 JavaScript 的高级数组方法(例如map()和filter() )简单地循环遍历 JSON 数组并合并数组元素的属性。
在 React 中实现
本指南中演示的示例涵盖了一个简单的用例,其中您的服务器向前端返回任务列表,您需要在每个任务旁边显示一个复选框以将其标记为已完成或尚未完成。此示例的一般用例是一个在线门户,经理为员工生成任务,员工在一天结束时通过将这些任务标记为已完成或未完成来更新这些任务。
集成来自 API 的数据
为了演示,假设所有任务都从 https://jsonplaceholder.typicode.com/todos 端点返回。上述端点返回一些虚拟 JSON,其中包含可参考此示例视为任务的待办事项列表。您需要一个状态来跟踪这些数据,以及一个发出GET请求以使用fetch API获取所有数据的函数。考虑以下代码:
import React,{useState,useEffect} from 'react';
import './App.css';
function App() {
const [tasks,setTasks]=useState([])
const getTasks=()=>{
fetch('https://jsonplaceholder.typicode.com/todos')
.then(response => response.json())
.then(json =>{
console.log(json)
}
useEffect(()=>{
getTasks();
},[])
return (
<div className="App">
</div>
);
}
export default App;
您需要在useEffect( )中调用getTasks()(如上所示),以便在组件第一次安装在 DOM 上时进行此 API 调用。
修改和合并数组元素的属性
检查控制台,您可以观察到todos数组已包含属性done。此外,端点返回了大量的todos ,因此使用filter()方法过滤数组,仅保留前 10 个 todo 以简化数据,并从每个 todo 中删除done属性。后者之所以这样做,是因为您的应用使用的 API 不会从服务器返回此属性。
const getTasks=()=>{
fetch('https://jsonplaceholder.typicode.com/todos')
.then(response => response.json())
.then(json =>{
let allTasks=json;
allTasks=allTasks.filter((currentTask)=>{return currentTask.id<=10 && {id:currentTask.id,title:currentTask.title}})
console.log('taks: ',allTasks)
})
}
已完成属性是此数据的外部属性,必须仅保留在前端。下一步是将此属性与数组合并,并使用map()方法默认为每个元素将其设置为false。您还应该将状态设置为allTasks。
allTasks=allTasks.map((currentTask)=>{
return {...currentTask, completed:false}
})
setTasks(allTasks)
在 DOM 上渲染数据
使用组件循环,遍历任务数组并将它们呈现在 DOM 上,并且每个任务旁边都有一个受控输入复选框。
return (
<div className="App">
{
tasks && tasks.map(task=>{
return(
<p key={task.id}>{task.title} <input onChange={()=>handleChange(task.id)} type="checkbox" checked={task.completed}/></p>
)
})
}
</div>
);
您可以利用API 返回的每个任务的id作为其key。复选框与您的状态数据一致,使其成为受控组件。选中或取消选中复选框时,您需要触发一个函数来检查任务是否已标记为已完成并相应地修改该属性。将onChange事件侦听器附加到复选框输入并触发一个以任务的id作为参数的函数。
访问和修改外部属性
在handleChange()方法内部,循环遍历您的任务并反转id 与传递的 id匹配的任务的完成属性。
const handleChange=(id)=>{
let temp=tasks;
temp=temp.map((t)=>{
if(t.id===id)
t.completed=!t.completed
return t;
})
setTasks(temp)
console.log(id)
}
看一下下面的完整代码。
import React,{useState,useEffect} from 'react';
import './App.css';
function App() {
const [tasks,setTasks]=useState([])
const getTasks=()=>{
fetch('https://jsonplaceholder.typicode.com/todos')
.then(response => response.json())
.then(json =>{
let allTasks=json;
allTasks=allTasks.filter((currentTask)=>{return currentTask.id<=10 && {id:currentTask.id,title:currentTask.title}})
console.log('taks: ',allTasks)
allTasks=allTasks.map((currentTask)=>{return {...currentTask, completed:false}})
setTasks(allTasks)
})
}
useEffect(()=>{
getTasks();
},[])
useEffect(()=>{
console.log(tasks)
},[tasks])
const handleChange=(id)=>{
let temp=tasks;
temp=temp.map((t)=>{
if(t.id===id)
t.completed=!t.completed
return t;
})
setTasks(temp)
console.log(id)
}
return (
<div className="App">
{
tasks && tasks.length>0 && tasks.map(task=>{
return(
<p key={task.id}>{task.title} <input onChange={()=>handleChange(task.id)} type="checkbox" checked={task.completed}/></p>
)
})
}
</div>
);
}
export default App;
结论
您可以使用 JavaScript 方法(例如map()和filter() )来方便地合并 JSON 响应中数组元素的属性。合并外部属性是一种很好的技术,因为它允许您按照自己想要的方式处理前端的数据,但您必须确保将数据库期望的相同结构的数据发送回服务器。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~