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,
})));
}
)});
我的 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,
})));
}
)});