我是React的新手,并且使用React钩子。我有一个功能组件,需要在页面上显示一些信息。我收到并正确返回Jobs数组,可以在其中进行迭代并成功显示其信息,但也想接收另一个数组:location
。该数组基于jobs
数组:我需要首先接收jobs
,然后获取其位置ID,然后接收信息,并将其放入我的位置数组中,以便以后在我的信息页面中使用。问题是,当我想在位置中进行迭代时,在表单中,而不是在文本前面实际显示location.country
时,它在表单中重复了JSX文本“ Location:” 3次(我有3个工作对象)。我知道我必须将该位置数组保存在useEffect
中,但是它仅接受2个参数。这是我的代码:
function fetchJSON (...args) {
return fetch('/api/jobs/list-jobs', { headers: headers })
.then(r => {
if (!r.ok) {
throw new Error('HTTP error ' + r.status)
}
return r.json()
})
}
function useJobs () {
const [jobs, setJobs] = React.useState([])
const [locations, setLocations] = React.useState([])
React.useEffect(() => {
fetchJSON('/api/jobs/list-jobs', { headers: headers })
.then(setJobs)
}, [])
React.useEffect(() => {
for (const job of jobs) {
fetchJSON(`/api/jobs/view-location/${job.location}/`, { headers: headers })
.then(setLocations)// *** Need to handle #6 here
}
}, [jobs])
return [jobs, locations]
}
export default function Jobs () {
const classes = useStyles()
const [jobs, locations] = useJobs()
return (
{jobs.map(job => (
<>
<div className={classes.root} key={job.id}>
<Row>
<Col style={{ color: 'black' }}>Title:{job.title} </Col>
<Col>Company Name:{job.company_name} </Col>
<Col style={{ color: 'black' }}>Internal Code:{job.internal_code} </Col>
</Row>
{locations.map(location => (
<Col key={location.id} style={{ color: 'black' }}>Location:{location.country}</Col>))
}
我有3个这样的作业对象,对于每个作业对象,我想根据在useEffect中收到的job.location
位置数组来打印正确的位置。 jobs
数组的所有其他字段均正常工作。如何正确实现位置部分?
答案 0 :(得分:1)
您获取单个作业的位置数据,但仅在使用.then(setLocations)
时覆盖位置状态
您必须改为将位置存储为以工作ID为键的对象
function useJobs () {
const [jobs, setJobs] = React.useState([])
const [locations, setLocations] = React.useState({})
React.useEffect(() => {
fetchJSON('/api/jobs/list-jobs', { headers: headers })
.then(setJobs)
}, [])
React.useEffect(() => {
for (const job of jobs) {
fetchJSON(`/api/jobs/view-location/${job.location}/`, { headers: headers })
.then((locations) => {
setLocations(prev => ({...prev, [job.id]: locations}))
})
}
}, [jobs])
return [jobs, locations]
}
但是,对您来说,更好的方法是使用Promise.all一次更新所有位置
function useJobs () {
const [jobs, setJobs] = React.useState([])
const [locations, setLocations] = React.useState({})
React.useEffect(() => {
fetchJSON('/api/jobs/list-jobs', { headers: headers })
.then(setJobs)
}, [])
` React.useEffect(() => {
async function fetchLocations() {
const promises = [];
for (const job of jobs) {
promises.push(fetchJSON(`/api/jobs/view-location/${job.location}/`, { headers: headers })
.then((locations) => {
return {[job.id]: locations }
}))
}
const data = await Promise.all(promises);
setLocations(prev => Object.assign({}, ...data))
}
fetchLocations();
}, [jobs])
return [jobs, locations]
}
现在您必须注意,与每个工作ID对应的位置只是一个对象,而不是一个数组(根据聊天中的讨论),因此您不需要映射
{locations[job.id] && <Col key={locations[job.id].id} style={{ color: 'black' }}>Location:{locations[job.id].country}</Col>}