Skip to content
Advertisement

Creating table with data from API using Redux

I’m attempting to get information about NBA teams using Redux, then put that data into a table. Right now I’m able to get the data from the API, but I’m struggling to figure out the correct syntax to display a table with the data I collect using Redux (I usually use getContext and am trying to familiarize myself with Redux more).

This is my App.js

import React, { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { getTeams, getTable } from "./features/teams/teamsSlice";
import { Button } from "@mui/material";
import rsLogo from "./logo-with-name.png";
import "./App.css";

function App() {
  const dispatch = useDispatch();
  const { teams } = useSelector((state) => state.teams);
  const { table } = useSelector((state) => state.table);

  useEffect(() => {
    dispatch(getTeams());
  }, [dispatch]);
  console.log(teams);
  console.log(table);
  return (
    <div className="App">
      <header className="App-header">
        <img src={rsLogo} className="App-logo" alt="logo" />
      </header>
      <main>
        <Button
          variant="contained"
          target="_blank"
          onClick={() => dispatch(getTable(teams))}
          size="large"
          sx={{ m: 2, bgcolor: "#00003C" }}
          disableElevation
        >
          Show Teams
        </Button>
        {table}
      </main>
    </div>
  );
}

export default App;

This is my store.js

import { configureStore } from "@reduxjs/toolkit";
import teamsReducer from "../features/teams/teamsSlice";

const store = configureStore({
  reducer: {
    teams: teamsReducer,
  },
});

export default store;

And this is teamsSlice.js

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";

export const getTeams = createAsyncThunk(
  "teams/getTeams",
  async (dispatch, getState) => {
    return await fetch("https://www.balldontlie.io/api/v1/players").then(
      (res) => {
        return res.json();
      }
    );
  }
);

const teamsSlice = createSlice({
  name: "team",
  initialState: {
    teams: [],
    table: "",
    status: null,
  },
  reducers: {
    getTable(teams, action) {
      console.log("teams is ", teams);
      console.log("action is ", action);
      return <div>test</div>;
    },
  },
  extraReducers: {
    [getTeams.pending]: (state, action) => {
      state.status = "loading";
    },
    [getTeams.fulfilled]: (state, action) => {
      state.status = "success";
      state.teams = action.payload;
    },
    [getTeams.rejected]: (state, action) => {
      state.status = "failed";
    },
  },
});

const { actions, reducer } = teamsSlice;

export const { getTable } = actions;

export default teamsSlice.reducer;

I haven’t yet created the actual table, I’m just trying to get the syntax correct for being able to click a button and return a table based on data from the store.

Could anyone tell me what I’m doing wrong?

Answer

Since you are using redux and your request is not in the file it is important to keep an eye on changes to the object you need the information for, this is one way to do it:

import React, { useState, useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { getTeams, getTable } from "./features/teams/teamsSlice";
import { Button } from "@mui/material";
import rsLogo from "./logo-with-name.png";
import "./App.css";

function App() {
  const dispatch = useDispatch();
  const { teams } = useSelector((state) => state.teams);
  const { table } = useSelector((state) => state.table);

  const [dataTable, setdataTable] = useState([]);

  useEffect(() => {
    dispatch(getTeams());
  }, [dispatch]);

  useEffect(() => {
    if(table) setdataTable(table);
  }, [table])
  
  return (
    <div className="App">
      <header className="App-header">
        <img src={rsLogo} className="App-logo" alt="logo" />
      </header>
      <main>
        <Button
          variant="contained"
          target="_blank"
          onClick={() => dispatch(getTable(teams))}
          size="large"
          sx={{ m: 2, bgcolor: "#00003C" }}
          disableElevation
        >
          Show Teams
        </Button>
        {dataTable}
      </main>
    </div>
  );
}

export default App;

with this, when the effect detects a change in that object it will put it in the state when it exists

Advertisement