为了账号安全,请及时绑定邮箱和手机立即绑定

React useState/useEffect hook 未正确返回信息

React useState/useEffect hook 未正确返回信息

慕勒3428872 2022-08-04 09:32:02
我是 React 的初学者,使用 React 钩子。我有一个函数组件,需要在页面上显示一些信息。我收到并正确返回 jobs 数组,我可以迭代它并成功显示其信息,但希望也接收另一个数组:。此数组基于数组:我需要先接收,然后获取其位置 ID,然后接收信息并将其放入我的位置数组中,以便稍后在我的信息页面中使用。问题是,在我的表单中,当我想迭代位置时,它实际上显示文本前面的位置,它在我的表单中重复JSX文本“Location:”三次(我有3个工作对象)。我知道我必须将该位置数组保存在我的中,但它只接受2个参数。这是我的代码:locationjobsjobslocation.countryuseEffectfunction 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.locationjobs
查看完整描述

1 回答

?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

您可以获取单个作业的位置数据,但仅在使用时覆盖位置状态.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>}



查看完整回答
反对 回复 2022-08-04
  • 1 回答
  • 0 关注
  • 119 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信