react hooks

注:下面hooks尽量不要套用在if判断里面,因为react会初始计算hooks的个数,如果后期因为一些判断导致数量有变化,会报错。如果非要在if里面使用,请保持if和else个数的相等

useState

useState可以代替类组件的setState,可以使用多个useState函数

let [count, setCount] = useState(0);
// 下面两种写法都可以
<div onClick={() => { setCount(count + 1) }> { count } </div>
<div onClick={() => { setCount(count => count + 1) }> { count } </div>

useEffect

相当于类组件的大部分生命周期函数,初始调用一次,第二个参数是一个数组,只有当数组中的元素发生变化的时候才能出发,一般数组中的元素都是基本数据类型或者不是太复杂的数据,可以使用多个

useEffect(() => {
	...
	return () => {
		// return 里面的函数相当于componentWillUnmount生命周期函数,通常做定时器的销毁或者其他一些操作
	}
}, [count, name]) // 第二个参数中任意一项发生变化都会触发,支持表达式的写法,比如count > 5 ? true : count,代表count > 5的时候会是一个常量5,不会再触发useEffect函数

注:有一个类似hooks叫useLayoutEffect,写法和用法和useEffect相同,但是有更高的优先级,执行更快,但是一般使用useEffect

createContext和useContext

import { createContext, useContext } from 'react';

const content = createContext();
const { Provider } = content;

function A() {
  return <div>
    <B></B>
  </div>
}

function B() {
  const value2 = useContext(content); // 只要通过useContext(content)调用,被Provinder
  return <div>
    <div> { value2.name } </div>
  </div>
}

function App() {
  return (
    <Provider value={{name: '张三'}}>  // value字段可以向下传递
      <A></A>
    </Provider>
  );
}

ref

function App() {
  const inp = useRef()
  return (
    <div>
      <input ref={inp} />  // 也可以ref={(refDom
      ) => {  }}
      <button 
        onClick={() => { 
          inp.current.value = Date.now()
         }}
      > 点击获取当前时间戳 </button>
    </div>
  )
}

// 如果子组件是函数式组件的话,通常使用forwardRef
import { forwardRef, useRef } from 'react';

function A(props, ref) {
  return <input ref={ref}/>
}

const AFef = forwardRef(A); // 可以使用ref,为函数式组件的第二个参数

function App() {
  const inp = useRef();
  return (
    <div>
      <AFef ref={inp} />
      <button 
        onClick={() => { 
          inp.current.value = Date.now()
         }}
      > 点击获取当前时间戳 </button>
    </div>
  )
}

// 但是上面这种写法会将整个子组件的ref元素全部导出,这是我们不需要的,我们需要的仅仅是对ref元素进行一些操作,这个时候就要用到useImperativeHandle了
import { useImperativeHandle, useRef, forwardRef } from 'react';

function A(props, ref) {
  let inpRef = useRef()
  useImperativeHandle(ref, () => ({
    focus: () => {
      inpRef.current.focus();
    },
    getData: () => {
      inpRef.current.value = 'hello world'
    }
  }), [])
  return <input ref={inpRef}/>
}

const AFef = forwardRef(A);

function App() {
  const inp = useRef();
  return (
    <div>
      <AFef ref={inp} />
      <button 
        onClick={() => { 
          console.log('inp', inp)
         }}
      > 点击获取当前时间戳 </button>
    </div>
  )
}

通过打印inp,可以得到
在这里插入图片描述
这个时候就可以进行自己想要操作的事情了

useCallback

function App() {
  let [count, setCount] = useState(0);
  const clickFunc = useCallback(() => {
    setCount(count + 1);
  }, [count]) // 当count发生变化的时候才会刷新值
  return (
    <div>
      { count }
      <button onClick={ clickFunc }> 点击 </button>
    </div>
  )
}

useMemo

为防止组件频繁刷新,useMemo第二个参数为数组,只有数组中的元素发生变化的时候才刷新

const A = useMemo(() => {

}, [count]) //只有count发生变化的时候才刷新

function App() {
  return <A></A>
}

useReducer

在某些场景下,useReducer 会比 useState 更适用,例如 state 逻辑较复杂且包含多个子值,或者下一个 state 依赖于之前的 state 等。

import { useReducer } from 'react';

const initState = {
  count: 0
}
const reducer = (state, action) => {
  const { type, payload } = action;
  console.log('type', type)
  switch(type) {
    case 'increment':
      return { ...state, count: state.count +  payload.step }
    case 'decrement':
      return { ...state, count: state.count - payload.step }
    default:
      break;
  }
}
function App() {
  const [state, dispatch] = useReducer(reducer, initState) // 接受两个参数,第一个是处理函数,第二个是初始数据,返回state数据和dispatch函数
  return <>
    <div>{ state.count } </div>
    <button onClick={() => { dispatch({ type: 'increment', payload: { step: 2 } }) }}> + </button>
    <button onClick={() => { dispatch({ type: 'decrement', payload: { step: 2 } }) }}> - </button>
  </>
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值