use context to manage state

This commit is contained in:
Ruidy Nemausat 2020-07-22 21:33:31 +02:00
parent de5c4def4d
commit 10df79e847
5 changed files with 81 additions and 28 deletions

View file

@ -1,5 +1,23 @@
import React, { FC } from "react";
import { makeStyles } from "@material-ui/core/styles";
import CircularProgress from "@material-ui/core/CircularProgress";
const Loader: FC = () => <div>Fetching data from server</div>;
const useStyles = makeStyles({
root: {
position: "absolute",
top: "50vh",
left: "50vw",
},
});
const Loader: FC = () => {
const classes = useStyles();
return (
<div className={classes.root}>
<CircularProgress />
</div>
);
};
export default Loader;

View file

@ -1,38 +1,20 @@
import React, { FC, useState, useEffect } from "react";
import React, { FC } from "react";
import { Container } from "@material-ui/core";
import { withGame, IGameState } from "../store/GameProvider";
import Loader from "./Loader";
import MatchItem from "./MatchItem";
import apiClient from "../api";
const MatchList: FC = () => {
const [games, setGames] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
apiClient
.get("/")
.then(({ data }) => {
setLoading(false);
setGames(data);
})
.catch((err) => {
setLoading(false);
console.error(err);
return <div>{JSON.stringify(err, null, 2)}</div>;
});
}, []);
return loading ? (
const MatchList: FC<IGameState> = ({ games, loading }) =>
loading ? (
<Loader />
) : (
<Container>
{games.map((game, i) => (
<MatchItem key={i} id={i} {...game} />
<MatchItem key={i} {...game} id={i} />
))}
</Container>
);
};
export default MatchList;
export default withGame((props: IGameState) => <MatchList {...props} />);

View file

@ -3,10 +3,13 @@ import { render } from "react-dom";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import GameProvider from "./store/GameProvider";
render(
<React.StrictMode>
<App />
<GameProvider>
<App />
</GameProvider>
</React.StrictMode>,
document.getElementById("root")
);

View file

@ -0,0 +1,50 @@
import React, { FC, createContext, useState, useEffect } from "react";
import apiClient from "../api";
import IGame from "../types/Game";
export interface IGameState {
games: IGame[];
loading: boolean;
setGames: React.Dispatch<React.SetStateAction<IGame[]>>;
}
export const GameContext = createContext<IGameState>({
games: [],
loading: true,
setGames: () => {},
});
const GameProvider: FC = ({ children }) => {
const [games, setGames] = useState<IGame[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
apiClient
.get("/")
.then(({ data }) => {
setLoading(false);
setGames(data);
})
.catch((err) => {
setLoading(false);
console.error(err);
return <div>{JSON.stringify(err, null, 2)}</div>;
});
}, []);
return (
<GameContext.Provider value={{ games, loading, setGames }}>
{children}
</GameContext.Provider>
);
};
export const withGame = (Component: any) => (props: any) => (
<GameContext.Consumer>
{(store) => <Component {...props} {...store} />}
</GameContext.Consumer>
);
export default GameProvider;

View file

@ -10,5 +10,5 @@ export default interface IGame extends IVideo {
side2: ISide;
competition: ICompetition;
videos: IVideo[];
id: string;
id: number;
}