一。 react中的key的作用
1. 和type一起, 作为标记同级组件唯一性的标志
对于type同, key同的元素, 只进行更新,而不是unmount然后create,这样减少了开销
例如isLoading?<><Son id="2"/><id="1"><>?<><Son id="1"><Son id="2"></>。只是交换位置, 而不用销毁重建
2. 在reconcileElement时, 比较key和type,如果唯一,就复用
3. 在Fiber的架构中, Fiber是链表结构, 需要很麻烦找到兄弟节点(silbiling.sibiling), 在mapreamining方法中, 用map(key, fiber),以方便定位到节点
key要保证唯一性和稳定(不要用index和math.random)
二、 react refs的应用和注意
https://zhuanlan.zhihu.com/p/40462264 (走了源码)
refs主要用于获取原生的元素,控制动画或者在数据流之外修改元素
用法是
1) both class component and functioncomponent: let ref = React.createRef(); <Input ref = {ref}/> ref.current= 原生html
2) both class component and functioncomponent:
2.1 callback refFun = (elemnt) => {ref = elem} <input ref={refFunc} />
2.2 <input ref= {(elem) => ref = elem} /> 2.2和2.1相比, 2.2会在其他组件回流的时候也重新挂载, 因为ref == ()=>{} 为false。
commitLayoutEffect -> commitAttachRef -> ref(instance)
commitMutationEffect -> commitDetechref -> ref(null);
3) only function compnent: hook: let ref = useRef() <input ref={ref} /> ref = 原生html
此外forwardRef用于ref传递, 父组件拿到子组件的ref, 并且可以用在hoc。
cont AgeWithRef = React.forwardRef(AgeInput);
<ArgeWithRef ref="myref" />
ArgeInput = (props, ref) =>{
<input ref={ref}>
}
在hoc中, forardRef接收两个参数forwardRef(props, ref)
三. react事件系统
https://segmentfault.com/a/1190000015725214(含源码)
1. 事件注册:对于syntevent(复合事件)会一直冒泡到Document, 在 document上进行事件注册,regirstryNameModule,这里面包含那个组件, 监听函数等。随着系统变大, 监听越多,react这样做可以简化和提高性能。
2. 事件派发:找到点击的对象,所有的都注册到一个大的对象, 然后派发到Fibernode
对synnaEvent的组织冒泡不一定旗下, 需要stopImmediateProprgate
四。 生命周期
五。 组件通信
1. Context (react-rudex, router/history/match)
createContext, Provider 只能传一个值
2. 单一的static contextType = MyContext;
class MyClass extends React.Component {
static contextType = MyContext;
render() {
let value = this.context;
/* 基于这个值进行渲染工作 */
}
}
3.多个 useContext
注意事项:valueprops是对象, 会导致重复多次渲染
原理:遇到provider,把值存入栈中 (pushProvider)
popProvider 完成调度, 这样保证顺序不能乱
六.hook
Hook之前函数组件
无状态,无复用,只能单纯的展示组件
仅用class component,难以实现贡献逻辑
1. hook可以实现复用状态逻辑,hook更好的颗粒度
2. 复杂组件变得难以理解,class不好压缩,,热替换不稳定
3. 难以理解的class
引入hook
1. useState useReducer。 函数可以存储和改变状态值
4. 如果选择
尽量使用func组件
reacthook 16.7
useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。
useEffect在每个渲染后都执行, 而不用componentdidUpdate/componentDidiMount
与 componentDidMount 或 componentDidUpdate 不同,使用 useEffect 调度的 effect 不会阻塞浏览器更新屏幕,这让你的应用看起来响应更快。大多数情况下,effect 不需要同步地执行。
你可能认为需要单独的 effect 来执行清除操作。但由于添加和删除订阅的代码的紧密性,所以 useEffect 的设计是在同一个地方执行。如果你的 effect 返回一个函数,React 将会在执行清除操作时调用它:
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
// Specify how to clean up after this effect:
return function cleanup() {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
Hook 允许我们按照代码的用途分离他们
请记得 React 会等待浏览器完成画面渲染之后才会延迟调用 useEffect,因此会使得额外操作很方便。
七。 优化
1. 减少不必要的渲染
shouldComponentUpdate(true、false), PureComponent, usMemo
总的来说比较props,prepros
2.数据缓存
比较deps updateMemeoriedstate
3.尽量不艺使用jsx内链的方式(render, child, context)
router是用component会导致shiyongcreateElememt, 导致性能不好。应使用render/children
4.不要滥用context, props (不偏于维护, 子节点都会变,同props)
5. 懒加载,长页列表,分页
6. 减少http请求