Массив не отображает все элементы внутри него React JavaScript - PullRequest
1 голос
/ 07 мая 2020

Я получаю некоторую информацию от API на основе некоторых идентификаторов. есть 3 объекта задания, каждое задание имеет массив тегов, и в каждом массиве есть несколько идентификаторов, которые отправляются в API для возврата информации тега:

function useJobs () {
  const [jobs, setJobs] = React.useState([])
  const [locations, setLocations] = React.useState({})
  const [departments, setDepartments] = React.useState({})
  const [tags, setTags] = React.useState({})

  React.useEffect(() => {
    async function fetchTags () {
      const tPromises = []
      for (const job of jobs) {
        for (const tag of job.tags) {
          console.log(tag)
          tPromises.push(fetchJSON(`/api/jobs/view-tag/${tag}`, { headers: headers })
            .then((tags) => {
              return { [job.id]: tags }
            }))
        }
      }
      const dData = await Promise.all(tPromises)
      console.log(dData)
      setTags(prev => Object.assign({}, ...dData))
    }
    fetchTags()
  }, [jobs])

  return [jobs, locations, departments, tags]
}
export default function Jobs () {
 const [jobs, locations, departments, tags] = useJobs()
.....
{jobs.map(job => (
   {tags[job.id] && <Col key={tags[job.id].id}>Tags:{tags[job.id].name} </Col>}
)}
....
}

проблема в том, что только один элемент из каждого массива тегов для каждого задания. например, если массив равен [1,2,3], а затем преобразуется в [Css,Js,HTML], отображается только Css. Как я могу исправить эту проблему?

изменить:


  React.useEffect(() => {
    async function fetchTags () {
      const tPromises = []
      for (const job of jobs) {
        for (const tag of job.tags) {
          console.log(tag)
          tPromises.push(fetchJSON(`/api/jobs/view-tag/${tag}`, { headers: headers })
            .then((tags) => {
              return { [job.id]: tags }
            }))
        }
      }
      const dData = await Promise.all(tPromises)
      const tags = dData.reduce((acc, item) => {
        const [key, value] = Object.entries(item)
        if (acc[key]) {
          acc[key].push(value)
        } else {
          acc[key] = [value]
        }
        return acc
      }, {})
      setTags(prev => ({ ...prev, ...tags }))
      console.log(dData)
      setTags(prev => Object.assign({}, ...dData))
    }
    fetchTags()
  }, [jobs])

  return [jobs, locations, departments, tags]
}

1 Ответ

1 голос
/ 07 мая 2020

Данные, которые вы получаете от обещания.all, будут иметь несколько тегов для одного и того же jobId, поэтому вы не можете напрямую объединить этот объект, вместо этого вам нужно обработать его, чтобы преобразовать его в objectId для сопоставления массива тегов

  const dData = await Promise.all(tPromises)
  const tags = dData.reduce((acc, item) => {
      const [key, value] = Object.entries(item)[0];
      if(acc[key]) {
         acc[key].push(value);
      } else {
         acc[key] = [value];
      }
      return acc;
  }, {})
  setTags(prev => ({...prev, ...tags}))

как только вы это сделаете, вы можете сопоставить теги и отобразить их

   {tags[job.id] && tags[job.id].map(tag => <Col key={tags[job.id].id}>Tags:{tag.name} </Col>)}
...