Skip to content

Commit

Permalink
Add context to track loading state
Browse files Browse the repository at this point in the history
  • Loading branch information
lortimer committed Aug 27, 2023
1 parent d044451 commit 88b9d2d
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
52 changes: 52 additions & 0 deletions src/contexts/LoadingContext.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { useContext, useState } from "react";
import { LoadingContext, LoadingContextProvider } from "./LoadingContext";
import { render, screen } from "@testing-library/react";
import { ChildrenProps } from "../utilities/children-props";
import { UserEvent } from "@testing-library/user-event/dist/types/setup/setup";
import userEvent from "@testing-library/user-event";

describe("LoadingContext", () => {
let user: UserEvent;
beforeEach(() => {
user = userEvent.setup();
render(
<StubProvider>
<StubComponent/>
</StubProvider>
);
});
test("provides method to start loading", async () => {
const startButton = screen.getByRole("button", { name: "Start Loading" });
await user.click(startButton);

expect(screen.getByText("LOADING: true")).toBeInTheDocument();
});
test("provides method to finish loading", async () => {
const startButton = screen.getByRole("button", { name: "Start Loading" });
await user.click(startButton);

const finishButton = screen.getByRole("button", { name: "Finish Loading" });
await user.click(finishButton);

expect(screen.getByText("LOADING: false")).toBeInTheDocument();
});
});

const StubProvider = ({ children }: ChildrenProps) => {
const [isLoading, setIsLoading] = useState(false);
return (<>
<LoadingContextProvider setIsLoading={setIsLoading}>
LOADING: {isLoading ? "true" : "false"}
{children}
</LoadingContextProvider>
</>);
};

const StubComponent = () => {
const { startLoading, finishLoading } = useContext(LoadingContext);

return (<>
<button onClick={startLoading}>Start Loading</button>
<button onClick={finishLoading}>Finish Loading</button>
</>);
};
34 changes: 34 additions & 0 deletions src/contexts/LoadingContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React, { createContext, Dispatch, SetStateAction, useCallback } from "react";
import { ChildrenProps } from "../utilities/children-props";

type LoadingContextValue = {
startLoading: () => void,
finishLoading: () => void,
}

const defaultValue: LoadingContextValue = {
startLoading: () => {},
finishLoading: () => {}
};

export const LoadingContext = createContext<LoadingContextValue>(defaultValue);

type LoadingContextProviderProps = ChildrenProps & {
setIsLoading: Dispatch<SetStateAction<boolean>>
}

export const LoadingContextProvider = ({ children, setIsLoading }: LoadingContextProviderProps) => {
const startLoading = useCallback(() => {
setIsLoading(true);
}, [setIsLoading]);

const finishLoading = useCallback(() => {
setIsLoading(false);
}, [setIsLoading]);

return (
<LoadingContext.Provider value={{ startLoading, finishLoading }}>
{children}
</LoadingContext.Provider>
);
};

0 comments on commit 88b9d2d

Please sign in to comment.