# 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);
```