- 小知识: 父组件的重新渲染会引起子组件的props发生改变, 所以memo默认是shallow compare
- 何时使用: 取消父组件引起的不必要子组件渲染时
- 针对对象: memo仅仅针对props, 不会干涉子组件的state或者store或者context引起的渲染
- 默认比较方法: shallow compare, 修改:
import { memo } from 'react';
const myComponent = (props) => {...}
const areEqual = (prevProps, nextProps) => {...}
export default memo(MyComponent, areEqual);- 讨论前提: data is immutable
- 注意事项: function is mutable
- 引用比较: 针对0个{}的有效
- 浅比较: 针对只有1个{}的对象有效
- 深比较: 针对大于1个{}的对象有效
import deepEqual from 'fast-deep-equal';
import { equal } from 'fast-shallow-equal';
const getType = (sth) => {
  return Object.prototype.toString.call(sth).slice(8, -1);
}
const deepObject = (obj) => {
  const keys = Object.keys(obj);
  for (let i = 0; i < keys.length; i++) {
    const type = getType(obj[keys[i]]);
    if (type === 'Object' || type === 'Array') return true
  }
  return false
}
export const smartStrictEqual = (prev, next) => {
  const prevType = getType(prev);
  const nextType = getType(next);
  if (prevType !== nextType) return Object.is(prev, next);
  if (prevType === 'Array') return deepEqual(prev, next);
  if (prevType !== 'Object') return Object.is(prev, next)
  if (deepObject(prev) || deepObject(next)) return deepEqual(prev, next)
  return equal(prev, next)
}- 作为内部元素
// A的re-render会引起B的re-render
const ComponentA = () => (
  <ComponentB/>
)- 作为props传入
// A的re-render不会引起B的re-render
// App的re-render会引起A和B的re-render
const App = () => (
  <ComponentA>
    <ComponentB/>
  <ComponentA/>
)- 内部元素: A的re-render会引起B的re-render
- props传入:
- App的re-render才会引起B的re-render,A不会;
- B的re-render势必引起A的re-render, 因为B作为props传入了A
- 对A使用memo是无效的,因为children中包含函数,结果一定不同
 
const C0 = (props) => {
  return (
    <div>
      C0 Component
      <C1>
          <C2>
            <C3/>
          </C2>
      </C1>
    </div>
  )
}- 背景: 无任何memo- 问题: C0re-render时, 哪些组件会跟着re-render?
- 分析: C1,C2,C3都会re-render, 因为字面上,它们都是C0的子组件
 
- 问题: 
- 背景: 除C0外全部使用memo, 采用smartStrictEqual方法- 问题: C0re-render时, 哪些组件会跟着re-render?
- 分析:
- C3的- props中无children,使用memo能阻止渲染;
- C2的- props中有children,memo无法阻止渲染;
- C1的- props中有children, memo无法阻止渲染;
 
 
- 问题: 
- 解决方案:
- 自定义比较方法,忽略对children的比较
- 作为props的函数,在传入前要进行useCallback, 要注意添加适当的deps
 
- Container和- Contained之间存在数据传递
- 灰层数据传入需要通过- Container
- Container和- Contained强- 耦合
- High Order Component和- Low Order Component之间存在数据传递
- 灰层数据传入需要通过- High Order Component
- High Order Component和- Low Order Component低- 耦合
- 能够优雅地多层嵌套
- Provider和- Render Component之间存在数据传递
- 灰层数据传入无需经过- Provider层中继
- Provider和- Render Component低- 耦合
- 多层嵌套可以说是非常丑陋
- 可读性很强,能够一眼看出- 组件间的关系
- Parent和- Children之间不存在数据传递
- 灰层数据传入无需经过- Provider层中继
- Parent和- Children弱- 耦合
- 可以优雅地多层嵌套,就像HTML一样
- 可读性强




