在学习 React 时,我们总会遇到在 TS 和 JS 之间切换来开发多个项目,而有时会忘记 TS 的语法,所以编写一下 React 结合 TS 开发时的一些总结知识点,以便后续回顾用。
**说明:**这只是总结 React 与 TS 结合使用时的写法回顾,并不是介绍钩子函数的使用。
这节主要是回顾 useState
钩子函数的 TS 的写法。实例如下:
type AuthUserProp = {
name: string;
email: string;
};
const UseStartProps: React.FC = () => {
const [authUser, setAuthUser] = useState<AuthUserProp | null>(null);
const [isLogin, setIsLogin] = useState<boolean>(false);
return (
<div>
<h2>useStart 使用实例</h2>
<button
onClick={() => {
setIsLogin(true);
setAuthUser({ name: "Tom", email: "tom@example.com" });
}}
>
登录
</button>
<button
onClick={() => {
setIsLogin(false);
setAuthUser(null);
}}
>
登出
</button>
{isLogin ? (
<div>
<p>{authUser?.name}</p>
<p>{authUser?.email}</p>
</div>
) : (
<div>还未登录</div>
)}
</div>
);
};
export default UseStartProps;
这节主要是回顾 useReducer
钩子函数的 TS 写法,以及 TS 联合类型
使用方式。实例如下:
type CounterState = {
count: number;
};
type UpdateAction = {
type: "increment" | "decrement";
payload: number;
};
type ResetAction = {
type: "reset";
};
type CounterAction = UpdateAction | ResetAction; // 因为重置操作并不需要type这个参数,所以通过TS的类型推导来做判断
const UseReducerProps: React.FC = () => {
const initialState = { count: 0 };
function reducer(state: CounterState, action: CounterAction) {
switch (action.type) {
case "increment":
return { count: state.count + action.payload };
case "decrement":
return { count: state.count - action.payload };
case "reset":
return initialState;
default:
return state;
}
}
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<h2>useReducer 使用实例</h2>
Count: {state.count}
<button onClick={() => dispatch({ type: "increment", payload: 10 })}>
添加 10
</button>
<button onClick={() => dispatch({ type: "decrement", payload: 10 })}>
减去 10
</button>
<button onClick={() => dispatch({ type: "reset" })}>重置</button>
</div>
);
};
export default UseReducerProps;
这节主要是回顾 useContext
钩子函数的 TS 写法,以及 useContext 于 useStart 钩子函数使用时的写法。实例如下:
// ThemeContext.tsx
type ThemeContextProviderProps = {
children: React.ReactNode;
};
export const ThemeContext = createContext(theme);
export const ThemeContextProvider = ({
children,
}: ThemeContextProviderProps) => {
return (
<ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
);
};
// Box.tsx
const Box: React.FC = () => {
const theme = useContext(ThemeContext);
return (
<div
style={{
backgroundColor: theme.secondary.main,
color: theme.secondary.text,
}}
>
Theme context
</div>
);
};
export default Box;
// UserContext.tsx
type AuthUser = {
name: string;
email: string;
};
type UserContextType = {
user: AuthUser | null;
setUser: React.Dispatch<React.SetStateAction<AuthUser | null>>;
};
type UserContextProviderProps = {
children: React.ReactNode;
};
// 这里可以写成 export const UserContext = createContext({} as UserContextType),但是不建议这这样,这样做不好判断context的值是否为空
export const UserContext = createContext<UserContextType | null>(null);
export const UserContextProvider = ({ children }: UserContextProviderProps) => {
const [user, setUser] = useState<AuthUser | null>(null);
return (
<UserContext.Provider value={{ user: user, setUser: setUser }}>
{children}
</UserContext.Provider>
);
};
// User.tsx
export const User = () => {
const userContext = useContext(UserContext);
const handleLogin = () => {
userContext?.setUser({
name: "Vishwas",
email: "asd@asd.com",
});
};
const handleLogout = () => {
userContext?.setUser(null);
};
return (
<div>
<button onClick={handleLogin}>Login</button>
<button onClick={handleLogout}>Logout</button>
<div>用户名: {userContext?.user?.name}</div>
<div>用户邮箱: {userContext?.user?.email}</div>
</div>
);
};
这节主要是回顾 useRef
钩子函数的 TS 写法。实例如下:
export const DomRef = () => {
const inputRef = useRef<HTMLInputElement>(null!);
useEffect(() => {
inputRef.current.focus();
}, []);
return (
<div>
<input type="text" ref={inputRef} />
</div>
);
};
export const MutableRef = () => {
const [timer, setTimer] = useState(0);
const interValRef = useRef<number | null>(null);
const stopTimer = () => {
if (interValRef.current) {
window.clearInterval(interValRef.current);
}
};
useEffect(() => {
interValRef.current = window.setInterval(() => {
setTimer((timer) => timer + 1);
}, 1000);
return () => {
stopTimer();
};
}, []);
return (
<div>
HookTimer - {timer} -
<button onClick={() => stopTimer()}>Stop Timer</button>
</div>
);
};