React-hooks

107 阅读1分钟

常用hooks

useState

组件状态管理钩子,存储和修改状态

useState 使函数组件能够使用state

let [count, setCount] = useState(100);

state 是要设置的状态

setState 是更新 state 的方法,只是一个方法名,可以随意修改。

initState 是初始的 state,可以是随意的数据,也可以是回调函数,但是函数必须是有返回值。

const App=()=>{
 const [count, setCount] = useState(0);
 return (
 <div>
  <div>点击了{count} 次</div>
  <Button onClick={() => { setCount(count + 1) }}>点击</Button>
 </div>
 )  
}


useEffect

useEffect 是 componentDidMount(组件挂载完成时触发)、componentDidUpdate(状态改变时触发)、componentWillUnmount(组件将要卸载时触发)这几个生命周期方法的统一。

useEffect(callback, array)

callback:回调函数,作用是处理副作用逻辑

callback 可以返回一个函数,用作清理

array(可选参数):数组,用于控制 useEffect 的执行

分三种情况空数组,则只会执行一次(即初次渲染 render ),相当于 componentDidMount。

非空数组,useEffect 会在数组发生改变时执行。

不填 array 这个数组,useEffect每次渲染都会执行。

useEffect(()=>{ 
// 副作用逻辑 
return ()=>{ 
// 清理副作用需要清理的内容 
// 类似于 componentWillUnmount 
} 
}, [])

数组为空,return里的在组件卸载时调用 数组里有值,依赖性更新时,return里的会调用

function HooksTest() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    console.log(`您点击了${ count }次按钮`)
    return () => {
      console.log('组件卸载或者更新了')
    }
  }, [count])
  return (
    <div>
      <div>你点击了{count}次</div>
      <Button onClick={() => { setCount(count + 1) }}>点击</Button>
    </div>
  )
}

useMemo useMemo 的用法类似 useEffect,常常用于缓存一些复杂计算的结果。useMemo 接收一个函数和依赖数组,当数组中依赖项变化的时候,这个函数就会执行,返回新的值。

因为useMemo缓存的是一个值,所以初始化的时候useMemo里的callback会自动调用一次

const memoValue = useMemo(callBack, array);

callback 是一个函数用于处理逻辑

array 是控制 useMemo 重新执行的数组, array 改变时才会重新执行 useMemo

useMemo 返回的是一个记忆值,是 callback 的返回值

function HooksTest() {
  const [num1, setNum1] = useState(0)
  const [num2, setNum2] = useState(99)
  return (
    <>
      <button onClick={() => setNum1(num1+1)}>name</button>
      <button onClick={() => setNum2(num2-1)}>content</button>
      <Son num1={num1}></Son>
    </>
  )
}

function Son({num1}) {
  const changeNum = (num) => {
    console.log('11')
    return num + '------'
  }
  //不使用useMemo的情况下,父组件num2改变这里也会调用  父组件更新子组件跟着更新
  // const num=changeName(num1)
  //这个时候我们点击 改变num2值的按钮,发现changeName 并没有被调用。
  //但是点击改变num1值按钮的时候,changeName被调用了。我们可以使用useMemo方法 避免无用方法的调用,当然一般我们changName里面可能会使用useState来改变state的值,那是不是就避免了组件的二次渲染。达到了优化性能的目的
  const num = useMemo(() => changeNum(num1), [num1])
  return (
    <div>
      <div>{num}</div>
    </div>
  )
}
export default Son;

useCallBack() useCallback和 useMemo一样,也是用于性能优化,但它返回的是缓存的函数

使用方法如下:

const callback=useCallBack(callBack, array);

useCallback会将我们传递给它的函数callBack返回,并且将这个结果缓存;当依赖array变更时,会返回新的函数

const set =new Set()
function HooksTest() {
  const [count, setCount] = useState(1);
    const [val, setVal] = useState('');
    const callback = useCallback(() => {
        console.log({count});
    }, [count]);
    set.add(callback);
    return <div>
        <h4>{count}</h4>
        <h4>{set.size}</h4>
        <div>
            <button onClick={() => setCount(count + 1)}>+</button>
            <input value={val} onChange={event => setVal(event.target.value)}/>
        </div>
        <Son callback={callback} />
    </div>;

}


function Son({callback}) {
  const [count, setCount] = useState(() => callback());
  useEffect(() => {
    setCount(callback());
    console.log('------')
  }, [callback]);
  return <div>
    {count}
  </div>

}

我们可以看到,每次修改count,set.size就会+1,这说明useCallback依赖变量count,count变更时会返回新的函数;而val变更时,set.size不会变,说明返回的是缓存的旧版本函数

useRef

useRef变化不会主动使页面渲染

function HooksTest() {
  const r = useRef(0);
  console.log(r);
  const add = () => {
    r.current += 1;
    console.log(`r.current:${r.current}`);
  };
  return (
    <div className="App">
      <h1>r的current:{r.current}</h1> <button onClick={add}>点击+1</button>
    </div>);

}

注意事项

警告:React Hook useEffect has a missing dependency: ‘click‘

在使用useEffect时,当我们将函数的声明放在useEffect函数外面时,会报eslint警告

解决:将函数放在useEffect里面

useEffect(()=>{
  function Test(){
  }
Test()
},[])


使用 // eslint-disable-line react-hooks/exhaustive-deps**

useEffect(() => { 
clickshow() 
}, [showConfirmation])// eslint-disable-line react-hooks/exhaustive-deps

function clickshow(){
...
}