useMemo

作用:缓存计算的结果,传入的依赖数据变化时,才执行传入的回调函数(渲染前触发)

useMemo(
  ()=>{}, //回调函数
  [] //依赖项
) //返回回调函数执行结果

useCallback

作用:缓存函数,依赖项改变返回新函数,不会执行函数

useCallback(
  ()=>{}, //缓存的函数
  [] //依赖项
) //返回回调函数

useEffect

概念:生命周期函数中的挂载、更新、将销毁,三个函数的组合

用途:请求数据

state更新会重新渲染组件,每次渲染结束时触发effect

useMemo -> render -> useEffect

useEffect(()=>{ //传入setup函数
  const id = setInterval(() => {
    setCount(c => c + 1);
  }, 1000);
  return () => clearInterval(id); //返回cleanup函数 重新渲染/销毁时执行
},[])

useReduce

作用:更新状态

import { useReducer, useEffect } from 'react';

const initialState = {
  count: 0,
  step: 1,
}; //初始值

function reducer(state, action) {
  const { count, step } = state;
  if (action.type === 'tick') {
    return { 
      count: count + step, 
      step 
    };
    // return {
    //   ...state,
    //   count: count + step
    // }
  } else if (action.type === 'step') {
    return { count, step: action.step };
  } else {
    throw new Error();
  }
} //返回state

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  const { count, step } = state;

  useEffect(() => {
    const id = setInterval(() => {
      dispatch({ type: 'tick' }); //触发reducer,传action
    }, 1000);
    return () => clearInterval(id);
  }, [dispatch]);

  return (
    <>
      <h1>{count}</h1>
      <input value={step} onChange={e => {
        dispatch({
          type: 'step',
          step: Number(e.target.value)
        });
      }} />
    </>
  );
}

useRef

作用:引用一个不需要渲染的值

const value = useRef(null) //返回对象{current: null}
value.current = 0 //改变ref值

改变 ref 不会触发重新渲染

// 父组件
const inputRef = useRef(null);
function handleClick() {
	inputRef.current.focus(); //调用
}
return <MyInput ref={inputRef} />;

// 子组件
import { forwardRef } from 'react';
const MyInput = forwardRef(({ value, onChange }, ref) => {
  return (
    <input
      value={value}
      onChange={onChange}
      ref={ref} //露出
    />
  );
});
export default MyInput;

forwardRef

作用:转发ref属性(比如要在父组件中调用子组件中某个DOM节点或者组件的ref)

useImperativeHandle

作用:向父组件露出自定义ref方法

// 父组件
import { useRef } from 'react';
import MyInput from './MyInput.js';

export default function Form() {
  const ref = useRef(null);
  function handleClick() {
    ref.current.focus();
    // 下方代码不起作用,因为 DOM 节点并未被暴露出来:
    // ref.current.style.opacity = 0.5;
  }
  return (
    <form>
      <MyInput label="Enter your name:" ref={ref} />
      <button type="button" onClick={handleClick}>
        Edit
      </button>
    </form>
  );
}


// 子组件
import { forwardRef, useRef, useImperativeHandle } from 'react';
const MyInput = forwardRef(function MyInput(props, ref) {
  const inputRef = useRef(null);
  useImperativeHandle(ref, () => {
    return {
      focus() { //调用:ref.current.focus()
        inputRef.current.focus();
      },
      scrollIntoView() {
        inputRef.current.scrollIntoView();
      },
    };
  }, []);
  return <input {...props} ref={inputRef} />;
});
export default MyInput;

useState

作用:设置状态变量

调用set函数只影响下一次渲染中的state

const [age, setAge] = useState(28);
const [name, setName] = useState('Edward');
const [todos, setTodos] = useState(() => createTodos());

setName('Taylor');
setAge(a => a + 1); //传递一个根据先前状态来计算新状态的函数(更新函数)

useContext、createContext

作用:创建context用来提供和读取

const ThemeContext = createContext(null); //默认context值 在外部定义
export default function App() {
  const [theme, setTheme] = useState('dark');
  return (
		<ThemeContext.Provider value={theme}> //改变context值
  		<Button /> //provider内组件可获取value
		</ThemeContext.Provider>
  );
}
function Button() {
  const theme = useContext(ThemeContext); //获取context
  return <button className={theme} />;
}