Overview
I have an app where I want to build some global state between pages in Next.js and I'm using React Context as a solution + TypeScript. I created the context (MusicContext) and provider (Music Provider) where I want to pass the state of the MusicProvider, which includes:
- playlistTitle
- setPlaylistTitle
- songsMatched
- setSongsMatched
- songsMissing
- songsMissing
Question
How can I correctly initialize the type Dispatch<SetStateAction<string>> as a context state? Right now, the issue is coming from here:
setPlaylistTitle: (value: string) => value,
setSongsMatched: (value: Array<ISong>) => value,
setSongsMissing: (value: Array<ISong>) => value,
Error
Type '(value: string) => string' is not assignable to type '() => Dispatch<SetStateAction<string>>'.ts(2322)
musicContext.ts(12, 3): The expected type comes from property 'setPlaylistTitle' which is declared here on type 'IMusicContext'
(property) IMusicContext.setPlaylistTitle: () => Dispatch<SetStateAction<string>>
React Context: MusicContext
// Imports: Dependencies
import { createContext, useContext, Dispatch, SetStateAction } from 'react';
// Imports: TypeScript Types
import { ISong } from '../types/types';
// TypeScript: Music Context
interface IMusicContext {
playlistTitle: string;
songsMatched: Array<ISong>;
songsMissing: Array<ISong>;
setPlaylistTitle: () => Dispatch<SetStateAction<string>>;
setSongsMatched: () => Dispatch<SetStateAction<string>>;
setSongsMissing: () => Dispatch<SetStateAction<string>>;
}
// React Context: Music
export const MusicContext = createContext<IMusicContext>({
// Data
playlistTitle: 'Default Text', // Button Title
songsMatched: [],
songsMissing: [],
// Set State (TODO: HOW DO I INITIALIZE THE SET STATE VALUES???)
setPlaylistTitle: (value: string) => value,
setSongsMatched: (value: Array<ISong>) => value,
setSongsMissing: (value: Array<ISong>) => value,
});
// React Context: useMusicContext
export const useMusicContext = () => useContext<IMusicContext>(MusicContext);
React Context: MusicProvider
// Imports: Dependencies
import { useState } from 'react';
// Imports: React Context
import { MusicContext } from './musicContext';
// Imports: TypeScript Types
import { ISong } from '../types/types';
// TypeScript Type: Props
interface IProps {
value: any;
children: JSX.Element;
}
// React Context: Provider
export const MusicProvider: React.FC<IProps> = ({ value, children }: IProps) => {
// React Hooks
const [playlistTitle, setPlaylistTitle] = useState<string>('');
const [songsMatched, setSongsMatched] = useState<Array<ISong>>([]);
const [songsMissing, setSongsMissing] = useState<Array<ISong>>([]);
return (
<MusicContext.Provider value={{ playlistTitle, songsMatched, songsMissing, setPlaylistTitle, setSongsMatched, setSongsMissing }}>
{children}
</MusicContext.Provider>
);
};
