I am using react with typescript, to make a page for managing a users files and folders.
The page contains three tabs, one for the users own files, one for files shared with him and his recycle bin.
I am thinking of handling the calls to the the storage api in a StorageProvider, which would have functions like FetchMyFiles, FetchRecycleBin, RenameFolder and also store the fetched data for use by underlying components.
Any child component would then be able to call the shared helper functions which would update the context for everyone. The main app component could for example call loadMyFolders when the tab is selected and a CreateFolder component could call createFolder.
Does this approach make sense in react, and if so, how do I update the folders state in the code below?
export const StorageContext = createContext<StorageContextType | undefined>(undefined);
type StorageContextType = {
myFolder: JsonFolder | undefined;
recycleBin: JsonFolder | undefined;
sharedFolder: JsonFolder | undefined;
loadMyFolder: (signal: AbortSignal) => Promise<void>;
loadRecycleBin: (signal: AbortSignal) => Promise<void>;
createFolder: (signal: AbortSignal, parentFolderId?: string, folderName?: string) => Promise<void>;
//... a bunch of other methods for interacting with the api and update the three states
}
type SwwStorageProviderProps = {
baseUrl: string;
children: ReactNode;
}
export default function StorageProvider(props: SwwStorageProviderProps) {
const [myFolder, setMyFolder] = useState<JsonFolder | undefined>(undefined);
const [recycleBin, setRecycleBin] = useState<JsonFolder | undefined>(undefined);
const [sharedFolder, setSharedFolder] = useState<JsonFolder | undefined>(undefined);
async function loadMyFolder(signal: AbortSignal): Promise<void> {
const url = props.baseUrl + 'Api/Folder/Get';
const myFolders = await getFolderFromSww(url, signal);
setMyFolder(myFolders);
}
//... other function implementations
return (
<StorageContext.Provider value={{
myFolder: myFolder,
recycleBin: recycleBin,
sharedFolder: sharedFolder,
loadMyFolder: loadMyFolder,
loadRecycleBin: loadRecycleBin,
createFolder: createFolder
}}>
{props.children}
</StorageContext.Provider>
);
}
2
Answers
In short, our project uses a similar method with
createContext()
to store commonly usedstates
andfunctions
(for example, commonAPI
callings) across pages.As long as this
FoldersContext
is shared by many smaller components and with many layers, it will be simpler than passing them down usingprops
one by one.And if you want to update the
state
in thisFoldersContext
, you just have to providesetter
methods (usually thesetState
methods) in theProvider
as well, for example,In
main.tsx
,In
storage.tsx
,In
App.tsx
,You can check more of its behaviours in the documentation.
This approach make sense, however there’s something wrong in your implementation: you save the functions used to modified the state in the state itself.