Skip to the content.

React

hooks

useEffect和useState

function Component() {
	const [a, setA] = useState(0);
	useEffect(()=>{
		const timer = setInterval(() => { setA(a + 1); }, 1000);
		return () => {
			clearInterval(timer);
		};
	}, []); // 第二个参数为[]空数组,后续react引发的渲染,都与此useEffect无关

}

组件挂载以后,并没有按照预期的执行setA(a + 1),累加,而是只执行了一次。

react的警告:Either include it or remove the dependency array. You can also do a functional update ‘setA(a =>…)’ if you only need ‘a’ in the ‘setA’ call.

如果修改为:cont timer = setInterval(() => { setA(a => a +1)}, 1000);

就按照预期执行了。

为什么?

useEffect传入空数组,则hooks只在组件挂载时候运行一次。而useEffect执行的时候,会创建一个闭包,将a保存到闭包中,且初始值为0。故每隔1s,就会执行setCount(0 + 1),因此,a的值不会超过1.

注意:useEffect依赖不传值,则hook在组件每次render的时候都会执行。

memo 系列

React.memo和useMemo区别

useMemo和useCallback区别

ref 系列

ref在React中非常特殊,React是单向数据流,而ref通过和useImperativeHandle组合,实现子组件传递方法给父组件,实现父组件调用子组件的目的。

妙用

Ref不仅仅能拿到组件的引用,还能创建一个mutable对象,配合useEffect,可以用来支持previousProps

function usePrevious(value) {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
}

useRef和forwardRef

useImperativeHandle

// 子组件

const someHandle = () => {
	// ...
}

useImperativeHandle(ref, () => ({
  someHandle
}));

  1. useRef 创建引用变量
  2. forwardRef将引用变量传递给子组件
  3. useImperativeHandle将子组件函数,添加到父组件的ref对象上

经典文章

组件库设计

组件定义

const MyComponent: React.FC<{text: string}> = ({text}) => {
    return React.useMemo(() => <div>{text}</div>, [text]);
}

MyComponent.defalutProps = {
    text: 'test'
}

不用React.memo原因:无法做到按需渲染。在使用useContext情况下,memo会使组件重渲染。

Function Component内部函数需要用useCallback包裹,保证性能

面试

最佳实践

跨平台设计

TODO