來我們今天先寫一個簡單的Provider,這個Provider沒有做效能優化,也沒有把hook集結在一起就一個很單純的Provider,然後ts的型別部分,因為快速寫給大家看先用any帶過,但記得在寫的時候不要用any來寫,不然這樣會失去typescript本身帶來的優點.
sample code:
import { createContext, Dispatch, useReducer, ReactNode } from 'react';
type IContextType = {
state: {
name: string;
};
dispatch: Dispatch<any>;
};
type UserType = {
children: ReactNode;
};
export const NameContext = createContext<IContextType>({} as IContextType);
const { Provider } = NameContext;
const reducer = (state: any, action: any) => {
switch (action.type) {
case 'set':
return {
...state,
name: action.payload
};
default:
return state;
}
};
const UserProvider: React.FC<UserType> = ({ children }) => {
const [state, dispatch] = useReducer(reducer, {
name: 'hello'
});
const value = { state, dispatch };
return <Provider value={value}>{children}</Provider>;
};
export { UserProvider };
然後我們用一個父層元件來wrap住一個Provider
import { UserProvider } from '@contexts/nameContext';
import Name from './Name';
const Prac = () => {
return (
<UserProvider>
<Name />
</UserProvider>
);
};
export default Prac;
接下來我們去Name component
import { useContext } from 'react';
import { NameContext } from '@contexts/nameContext';
const Name = () => {
const { state, _ } = useContext(NameContext);
const { name } = state;
return <div>{name}</div>;
};
export default Name;
接下來我們來寫一個最簡單的測試案例
import { render, screen, act } from '@testing-library/react';
import { UserProvider } from '@contexts/nameContext';
import Name from '../Name';
test.only('should get name from context', async () => {
render(
<UserProvider>
<Name />
</UserProvider>
);
const getName = screen.queryByText(/hello/i);
expect(getName).toBeTruthy();
});
在render的時候包住Name component我們就可以在Name的元件裡接收到context所回傳的值
接下來幾天會寫別種wrap Provider的方式