# ReactHooks **Repository Path**: flying-code/react-hooks ## Basic Information - **Project Name**: ReactHooks - **Description**: react hooks typescript 环境搭建 - **Primary Language**: TypeScript - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2020-09-10 - **Last Updated**: 2022-07-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # react hooks 基础 [官网文档](https://zh-hans.reactjs.org/docs/hooks-reference.html) ## useState ```javascript import React, { useState } from 'react'; function Example() { // 声明一个叫 "count" 的 state 变量 const [count, setCount] = useState(0); return (

You clicked {count} times

); } ``` **useState 用于设定组件的状态值** ## Effect Hook(useEffect) **用于处理组件中的生命周期** ```javascript import React, { useState, useEffect } from 'react'; function FriendStatus(props) { const [isOnline, setIsOnline] = useState(null); useEffect(() => { function handleStatusChange(status) { setIsOnline(status.isOnline); } ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange); // Specify how to clean up after this effect: return function cleanup() { ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange); //组件卸载时调用 }; }); if (isOnline === null) { return 'Loading...'; } return isOnline ? 'Online' : 'Offline'; } ``` ```typescript function useEffect(effect: EffectCallback, deps?: DependencyList): void; ``` * effect 生命周期调用方法 * deps Array 监听数组 ,可选 判断更新时是否执行 > 例子 ```typescript useEffect(() => { return () => { console.log("object") dispatch({type:'CLEARDATA'}) //组件卸载时调用 } }) ``` ## useCallback **返回一个 [memoized](https://en.wikipedia.org/wiki/Memoization) 回调函数** **`useCallback(fn, deps)` 相当于 `useMemo(() => fn, deps)`。** > 监听deps 更变 判断是否执行 避免非必要的执行和渲染 ```typescript const memoizedCallback = useCallback( () => { doSomething(a, b); }, [a, b], ); ``` ## useMemo **你可以把 `useMemo` 作为性能优化的手段,但不要把它当成语义上的保证。**将来,React 可能会选择“遗忘”以前的一些 memoized 值,并在下次渲染时重新计算它们,比如为离屏组件释放内存。先编写在没有 `useMemo` 的情况下也可以执行的代码 —— 之后再在你的代码中添加 `useMemo`,以达到优化性能的目的。 ## useRef **将组件实例化为一个对象** ```typescript const AddName: React.FC = () => { const inputRef = useRef(null); const inputAgeRef = useRef(null); const { state, dispatch } = useContext(storeContext); const {user} = state const handleChange = () => { const name = inputRef.current.value; dispatch({ type: 'CHANGENAME', name }); }; const handleAgeChange=()=>{ const age = inputAgeRef.current.value dispatch({type:'CHANGEAGE',age}) } return ( <> ); }; ``` ## useImperativeHandle **将ref组件中的方法暴露给父组件调用(参照vue中的$ref.form.submit())** ```typescript useImperativeHandle(VideoRef, () => ({ //暴露给父组件的方法 Seek: (time: number) => { if (videoTarget.current && Load) { if (time < duration) { videoTarget.current.seek(time); SetPause(false); } else { ToastShow('跳转时间有误!'); } } else { ToastShow('视频加载中!'); } }, })); ``` ## useContent **react hooks中的上下文 ,避免数据层层传递** ```typescript const value = useContext(MyContext ); //MyContext 是react.createContext()实例化的 store ``` - 使用 ```typescript import React from 'react'; import { storeContext } from '../stories'; interface IProvider{ store:{ state:any, dispatch:React.Dispatch, }, children?:React.ReactNode } const Provider = (props: IProvider) => { return {props.children}; }; export default Provider ``` [React官方Context文档](https://zh-hans.reactjs.org/docs/context.html) ## useReducer ```typescript const [state, dispatch] = useReducer(reducer, initialArg, init); ``` ## useContent + useReducer 实现redux ```typescript /* * @Author: LG * @Date: 2020-09-09 15:05:59 * @Description: 定义store * @path : /stories/index.ts * @Last Modified By: LG * @Last Modified Time: 2020-09-10 10:09:02 */ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import React from 'react'; export const initialState:any = { user:sessionStorage.user?JSON.parse(sessionStorage.user):{} }; export const storeContext = React.createContext(initialState); export const reducer = (state:any, action:any) => { switch (action.type) { case 'CHANGENAME': state.user.name=action.name sessionStorage.setItem('user', JSON.stringify(state.user)); return {...state} case "CHANGEAGE": state.user.age=action.age sessionStorage.setItem('user', JSON.stringify(state.user)); return {...state} case "CLEARDATA": sessionStorage.removeItem("user") state.user={} return {...state} } }; ``` ```typescript /* * @Author: LG * @Date: 2020-09-09 15:05:59 * @Description: 定义Provider * @path : /router/Provider.tsx * @Last Modified By: LG * @Last Modified Time: 2020-09-10 10:09:02 */ import React from 'react'; import { storeContext } from '../stories'; interface IProvider{ store:{ state:any, dispatch:React.Dispatch, }, children?:React.ReactNode } const Provider = (props: IProvider) => { return {props.children}; }; export default Provider ``` ```typescript /* * @Author: LG * @Date: 2020-09-09 15:05:59 * @Description: 初始化store * @path : /router/index.tsx * @Last Modified By: LG * @Last Modified Time: 2020-09-10 10:09:02 */ import React, { useReducer } from 'react'; import { BrowserRouter as Router, Route, Redirect, Switch } from 'react-router-dom'; import App from '../App'; import Home from '../views/Home'; import NotFound from '../views/NotFound'; import reduxApp from '../container/app' import { initialState, reducer } from '../stories'; import Provider from './Provider'; const Routes: React.FC = () => { const [state,dispatch] = useReducer(reducer,initialState) return ( ); }; export default Routes; ``` ```typescript /* * @Author: LG * @Date: 2020-09-09 15:05:59 * @Description: 使用store数据 * @path : /container/components/addName.tsx * @Last Modified By: LG * @Last Modified Time: 2020-09-10 10:09:02 */ /* eslint-disable @typescript-eslint/no-explicit-any */ import React, { useRef,useContext } from 'react'; import { storeContext } from '../../stories'; const AddName: React.FC = () => { const inputRef = useRef(null); const inputAgeRef = useRef(null); const { state, dispatch } = useContext(storeContext); const {user} = state const handleChange = () => { const name = inputRef.current.value; dispatch({ type: 'CHANGENAME', name }); }; const handleAgeChange=()=>{ const age = inputAgeRef.current.value dispatch({type:'CHANGEAGE',age}) } return ( <> ); }; export default React.memo(AddName); ```