React - api 数据已成功传递给组件(每个检查员)但未呈现

React - api data is being successfully passed to component(per inspector) but not being rendered

我的 api 数据已成功从我的 api 调用传递到 table 组件,但未呈现。

如果我在搜索播放列表后进入并编辑 table.js 文件,数据将正确呈现。 App.js...

const App = (props) => {
  const [playlists, setPlaylists] = useState([])
  const [searchString, setSearchString] = useState() //use instead of onsubmit 
  const isFirstRef = useRef(true);
  
  const search = (value) => {
    setSearchString(value)
  }

  useEffect(
    () => {
      if (isFirstRef.current) {
      isFirstRef.current = false;
      return;
      }
      let spotlist = Spotify.playlistsearch(searchString)
      let tablelist = []
      spotlist.then(val =>{
        val.forEach(element =>{
          tablelist.push(
            { 
              name: element.description,
              track_count: element.tracks.total,
            })
        } 
      )})
      setPlaylists(tablelist)
      }, [searchString] );

  return (
    <div className="App">
      <Searchform search={search}/>
      <Table playlists={playlists}/>
    </div>
  )
};

Playlists 道具在 PlayListTable 组件检查器下显示为存在,但未呈现。如果我在看到组件检查器中存在的数据后编辑文件,我就能够获取要呈现的数据。 Table.js

import React from 'react'
import { Icon, Label, Menu, Table } from 'semantic-ui-react'

const PlayListTable = ({ playlists }) => {
  return(
    <Table celled>
      <Table.Header>
        <Table.Row>
          <Table.HeaderCell>Playlist</Table.HeaderCell>
          <Table.HeaderCell>Track Count</Table.HeaderCell>
        </Table.Row>
      </Table.Header>
      <Table.Body>
       {playlists.map( (playlist) => {
          return (
              <Table.Row>
                <Table.Cell>
                  {playlist.name}
                </Table.Cell>
                <Table.Cell>
                  {playlist.track_count}
                </Table.Cell>
              </Table.Row>
              )
            }
          )
        }
      </Table.Body>
      <Table.Footer>
        <Table.Row>
          <Table.HeaderCell colSpan='3'>
            <Menu floated='right' pagination>
              <Menu.Item as='a' icon>
                <Icon name='chevron left' />
              </Menu.Item>
              <Menu.Item as='a'>1</Menu.Item>
              <Menu.Item as='a'>2</Menu.Item>
              <Menu.Item as='a'>3</Menu.Item>
              <Menu.Item as='a'>4</Menu.Item>
              <Menu.Item as='a' icon>
                <Icon name='chevron right' />
              </Menu.Item>
            </Menu>
          </Table.HeaderCell>
        </Table.Row>
      </Table.Footer>
    </Table>
  )
}

export default PlayListTable

我首先要注意的是,除非 searchString 发生某些变化,否则您的使用效果不会触发,因为它位于依赖项数组中。此外,我认为您的第一个 ref 条件阻止了第一个渲染的设置,因此它可能会导致问题。

最好查看之前的检查之类的东西,我以前使用过这里的常见钩子的解决方案:

当你说播放列表道具出现时,有实际价值吗?

在其他编辑中确保地图中的 return 值具有正确的键:https://reactjs.org/docs/lists-and-keys.html

问题

您可能收到了正确的数据,但没有在正确的时间更新您的状态。 spotlist returns 您正在链接的 Promise,但是 setPlaylists(tablelist) 调用在 before promise 链的 then 块之前排队被处理。 useEffect 回调是 100% 同步代码。

let spotlist = Spotify.playlistsearch(searchString);
let tablelist = [];
spotlist.then(val => { // <-- (1) then callback is placed in the event queue
  val.forEach(element => { // <-- (3) callback is processed, tablelist updated
    tablelist.push({ 
      name: element.description,
      track_count: element.tracks.total,
    });
  } 
)});
setPlaylists(tablelist); // <-- (2) state update enqueued, tablelist = []

解决方案 - 在 Promise 链中放置状态更新

您可以 forEach 到一个临时数组中,但是将响应数据映射到状态值是更“React”的处理方式。也比较简洁

Spotify.playlistsearch(searchString)
  .then(val => {
    setPlaylists(val.map(element => ({
      name: element.description,
      track_count: element.tracks.total,
    })));
  } 
)});