React Hooks的memo和useCallback

import React, { useState } from 'react';

const Child = (props) => {
  console.log(props, 'child-props');
  return <input type="number" />;
};

const Parent = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <div>count: {count}</div>
      <button onClick={() => setCount(count + 1)}>+1</button>
      <Child />
    </div>
  );
};

export default Parent;

每次父组件中点+1按钮都会触发子组件log(即子组件渲染),因为按钮触发了父组件重新渲染

 

import React, { useState, memo } from 'react';

const Child = memo((props) => {
  console.log(props, 'child-props');
  return <input type="number" />;
});

const Parent = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <div>count: {count}</div>
      <button onClick={() => setCount(count + 1)}>+1</button>
      <Child />
    </div>
  );
};

export default Parent;

使用memo包装子组件,父组件的重新渲染不会带着子组件一起渲染,因为子组件不依赖父组件任何props,所以此处点击+1按钮不会触发子组件log

 

import React, { useState, memo } from 'react';

const Child = memo((props) => {
  console.log(props, 'child-props');
  return <input type="number" />;
});

const Parent = () => {
  const [count, setCount] = useState(0);

  const onchange = (e) => {
    setCount(e.target.value);
  };

  return (
    <div>
      <div>count: {count}</div>
      <button onClick={() => setCount(count + 1)}>+1</button>
      <Child change={onchange} />
    </div>
  );
};

export default Parent;

此处父组件重新渲染,onchange函数会重新生成,新生成的函数会导致子组件重新渲染,所以此处点击+1按钮会触发子组件log。

 

import React, { useState, memo, useCallback } from 'react';

const Child = memo((props) => {
  console.log(props, 'child-props');
  return <input type="number" onChange={props.change} />;
});

const Parent = () => {
  const [count, setCount] = useState(0);

  const onchange = useCallback((e) => {
    setCount(e.target.value);
  }, []);

  return (
    <div>
      <div>count: {count}</div>
      <button onClick={() => setCount(count + 1)}>+1</button>
      <Child change={onchange} />
    </div>
  );
};

export default Parent;

使用useCallback包装函数,会缓存了每次渲染时 inline callback 的实例,不会每次都重新生成进而造成依赖组件重新渲染。所以此处点击+1按钮不会触发子组件log

posted @ 2021-10-28 15:12  卓扬  阅读(57)  评论(0编辑  收藏  举报