javascript - React useState/useEffect 钩子(Hook)未正确返回信息

标签 javascript arrays reactjs react-hooks

我是 React 和使用 React hooks 的初学者。我有一个功能组件需要在页面上显示一些信息。我正确接收并返回作业数组,我可以迭代它并成功显示其信息,但也想接收另一个数组:location。该数组基于 jobs 数组:我需要首先接收 jobs,然后获取其位置 id,然后接收信息并将其放入我的位置数组中以供使用稍后我的信息页面。问题是,在我的表单中,当我想要迭代位置时,它不会在文本前面实际显示 location.country ,而是会重复 JSX 文本“Location:”三次我的表格(我有 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 数组的所有其他字段都正常工作。如何正确实现位置部分?

最佳答案

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

关于javascript - React useState/useEffect 钩子(Hook)未正确返回信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61654475/

相关文章:

javascript - 如何在 React 中获取 Firestore 的文档 ID

javascript - 所有卡片均未设计样式

javascript - 路径上的 D3 事件不起作用

javascript - Redux Saga 是否选择返回可变状态?

c - 在邻接表中使用 DFS 并使用指针的指针数组

java - 如何从数组中删除所有重复项

css - 如何在构建语义 ui 时生成多个 semantic.<theme>.min.css 文件?

javascript - DIV 在页面上随机淡入

JavaScript - 无法在 Jest 测试中获取 jsdom 文档

C++ 应用程序在删除时崩溃