首页 > 解决方案 > React - api 数据已成功传递给组件(每个检查器)但未呈现

问题描述

我的 api 数据已成功从我的 api 调用传递到表组件中,但没有被渲染。

如果在搜索播放列表后我进入并对 table.js 文件进行编辑,则数据将正确呈现。应用程序.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 组件检查器下显示为存在,但未呈现。如果我在看到组件检查器中存在的数据后编辑文件,我就能够获取要呈现的数据。表.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

标签: javascriptreactjsfunctionrendering

解决方案


问题

您可能会收到正确的数据,但您没有在正确的时间更新您的状态。spotlist返回一个您从中链接的 Promise,但在处理 Promise 链的块之前setPlaylists(tablelist)调用已入队。回调是 100% 同步代码。thenuseEffect

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进入一个临时数组,但将响应数据映射到状态值是更“反应”的处理方式。它也更简洁。

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

推荐阅读