Reputation: 53
I'm attempting to render a table of stats from an NBA API. I'm using redux to store the user's selected players and requesting the API through my Table component. I retrieve the stats appropriately however it ends up infinitely requesting the API. I know that me setting a hook within an asynchronous request will cause this behavior but I'm not sure of a workaround at the moment. I think this is a lifecycle error, should I try using useEffect and have the player object from the redux store in the dependency array? Any input would be great. I'll post the code below.
Here's a screengrab of the behavior and console log when I log cData: https://i.sstatic.net/zeaFB.jpg
Table.js
const DataTable = () => {
const [completeData, setCompleteData] = React.useState([]);
const players = useSelector(state => state.players);
var cData = [];
const search = async val => {
try {
const res = await axios(
`https://www.balldontlie.io/api/v1/season_averages?player_ids[]=${val}`
);
const responseData = res.data.data;
console.log(responseData);
return responseData;
} catch (err) {
console.log(err);
}
};
return (
<div>
<h3>2019-2020 Season Averages</h3>
<Table responsive>
<thead>
<tr>
<th>Player</th>
<th>Points</th>
<th>Assists</th>
<th>Rebounds</th>
<th>Steals</th>
<th>Blocks</th>
<th>Turnovers</th>
</tr>
</thead>
<tbody>
{Object.keys(players).map(function(item, i) {
var currentPlayerData = {};
currentPlayerData = search(players[item])
.then(result => {
cData = JSON.parse(JSON.stringify(result[0]));
console.log(cData);
setCompleteData(old => [...old, cData]);
// setCurrentData(cData);
})
.catch(err => {
console.log(err);
});
})}
{completeData &&
completeData.map(function(item, i) {
console.log(item);
return (
<tr key={i}>
<td>{item.id}</td>
<td>{item.pts}</td>
<td>{item.ast}</td>
<td>{item.reb}</td>
<td>{item.stl}</td>
<td>{item.blk}</td>
<td>{item.turnover}</td>
</tr>
);
})}
</tbody>
</Table>
</div>
Upvotes: 0
Views: 3964
Reputation: 173
Try this approach (assuming that you want to get data from NBA API as soon as your component loads).
When your table component loads, in componentDidMount()
call a method for example call this.getNBAdata()
in your action.js which will get the data from API. Once you receive the data in .then()
you should dispatch an action with payload data to the reducer, which can we used by adding mapStatetoProps() your table component, so once you receive the data in your props variables it will reload/refresh that particular component and by the help of .map() you shall be able to display the data in table.
Action.js sample request:
export const getNBAData = () => {
return (dispatch) => {
Axios.get("http://nbadataendpoint.com")
.then(response => {
//you will get the data in response object
dispatch({ type: 'YOUR_SUCCESS', payload: 'SOME_VALUE' });
})
.catch(error => {
dispatch({ type: 'UNAUTHORISED', payload: 'SOME_VALUE'});
}
});
}
};
Upvotes: 1