react hook

react hook

最近实习有点忙,所以学习记录没来得及写。

HOC higher order components(HOC)

高阶组件是一个组件,接受一个参数作为组件,返回值也是一个组件的函数。高阶组件作用域强化组件,服用逻辑,提升渲染性能等。

mixin模式

javascript 复制代码
const customMixin = {
	componentDidMount() {
		console.log('componentDidmount')
	},
	say() {
		console.log(this.state.name)
	}
}
const App = React.createClass({
	mixins: [ customMixin ],
	getInitialState() {
		return {
			name:"alien"
		}
	}
})

mixins只能存在与creatreClass中,后来的React.createClass被废弃了。mixins会带开负面影响

  1. 引入了隐式依赖关系
  2. 不同的mixins之间可能会有先后顺序甚至是代码覆盖的问题

衍生方式-- 原型链继承

javascript 复制代码
const customMixin = {
	componentDidMount() {
		console.log('componentDidmount')
	},
	say() {
		console.log(this.state.name)
	}
}
function componentClassMixins(component, mixin) {
	for(let key in mixin) {
		Component.prototype[key] = mixin[key]
	}
}
class Index extends React.Component {
	constructor() {
		super()
		this.state = {name: 'alien'}
	}
	render () {
		return <div> hello world</div>
	}	
}
componentClassMixins(Index, customMixin)

HOC模式

将一个组件转换为另一个组件,经过包装后的组件,获得了多少强化,解决了原有组件的那些缺陷,节省了多少逻辑,这就是高阶组件的意义。
使用装饰器模式和函数包裹模式

对于class生命的有状态的组件,可以使用装饰器模式,对类组件进行包装

javascript 复制代码
function HOC(Component) {
	return class wrapComponent extends React.Component {
		constructor() {
			super()
			this.state = {
				name: "alien"
			}
		}
		render = () => <Component {...this.props} {...this.state} />
	}
}
@HOC
class Index extends React.Component {
	say() {
		const { name } = this.props
		console.log(name)
	}
	render() {
		return <div>hello, world<button onClick={this.say.bind(this)}> 点击</button>
	}
javascript 复制代码
@withStyles(styles)
@withRouter
@keepaliveLifeCycle
class Index extends React.Component {
	/*...*/
}
javascript 复制代码
function Index() {
	//
}
export default withStyles(styles)(withRouter(keepaliveLifeCycle(Index)))
补充设计模式--- 装饰器设计模式

装饰器就是将一段代码和另一端代码包装在一起的一种方式。

装饰器支持类和类的成员上的装饰器类型,包括属性,方法,getter和setter。

类修饰符一次性应用于整个类定义,装饰器函数使用单个参数调用,该参数就是要装饰的构造函数。

javascript 复制代码
function log(Class) {
	return (...args) => {
		console.log(args)
		return new Class(...args)
	}
}
@log
class Animal {
	constructor(name, age) {
		this.name = name
		this.age = age
	}
}
const cat = new Animal("hello", 1)
// ["hello", 2]
javascript 复制代码
function log(name) {
	return function decorator(Class) {
		return (..args) => {
			console.log(`log for ${name}:`, args)
			return new Class(...args)
		}
	}
}
@log(cat)
class Animal {
	constructor(name, age) {
		this.name = name
		this.age = age
	}
}
const cat = new Animal("hello world", 2)
// log for cat: ["hello world", 2]

类成员装饰器

  • target: 要修改属性的对象
  • name: 要修改的属性的名称
  • descriptor:要修改的属性描述符
javascript 复制代码
function readonly(target, name, descriptor) {
	descriptor.writable = false
	return descriptor
}
class Anmimal {
	@readonly age = 2
}
const cat = new Animal()
// {age: 2}
javascript 复制代码
function log(target, name, descriptor) {
	const original = descriptor.value
	if(typeof original === 'function') {
		descriptor.value = function(...args) {
			console.log(`log for args: ${args]`)
			try {
				return original.apply(this, args)
			} catch (e) {
				console.log(`Error: ${e}`)
				throw e
			}
		}
	}
	return descriptor
}
javascript 复制代码
class Animal {
	constructor(name) {
		this.name = name
	}
	@log
	sayHello(name) {
		console.log(`hello ${name}`)
	}
}
const cat = new Animal('hello')
cat.sayHello('jack')
javascript 复制代码
function log(name) {
	return function decorator(target, name, descriptor) {
		const original = descriptor.value
		if(typeof original == 'function') {
			console.log(`${name}`)
		}
		return descriptor
	}
}

学到这里感觉和继承有很深关联,回头学一学这个模块,然后产出一篇文章。

useState

异步批量是指在一次页面更新中如果涉及到多次state修改的时候,会合并多次state修改的结果得到最终结果而进行一次页面更新

  1. react可以管控的地方,是异步批量更新,比如事件函数,生命周期函数,组件内部同步代码
  2. react不能管控的地方,就是同步更新,settimeout,setinterval,原生dom等,包括promise都是同步批量更新。

useEffect

useEffect 被称为副作用钩子,这个 Hook 和 useState 一样是一个基础钩子。Effect Hook 可以让你在函数组件中执行副作用操作。

useEffect Hook 支持两个参数,第一个参数为一个函数表示副作用效应函数,默认情况下它在第一次渲染之后和每次更新之后都会执行。

第二个参数是一个数组,指定了第一个参数(副效应函数)的依赖项。只有该数组中的变量发生变化时,副效应函数才会执行。

useContext

Vue 中的 provide/inject Api

useReducer

javascript 复制代码
const [state, dispatch] = useReducer(reducer, initialArg, init);

使用 useReducer 还能给那些会触发深更新的组件做性能优化,因为你可以向子组件传递 dispatch 而不是回调函数。在某些场景下我们通常会将函数作为 props 传递到 child component 中去,这样的话,每次父组件 re-render 时即使我们并没有修改当作 props 的函数,子组件也会重新渲染。React 每次渲染都会重新执行组件函数,当重新执行父组件时会重新生成一个 callback 函数。因为 React 内部使用 Object.is 判断,所以 React 会认为子组件的 props 发生了变化。

useMemo

useCallback

第一个参数是一个函数,这个函数仅会在对应依赖项发生变化之后才会被重新生成,或者说这个函数被产生「记忆」。

第二个参数是一个数组,它表示第一个参数所依赖的依赖项,仅在该数组中某一项发生变化时第一个参数的函数才会「清除记忆」重新生成。

useRef

useRef Hook 的作用主要有两个:

  1. 多次渲染之间保证唯一值的纽带。useRef 会在所有的 render 中保持对返回值的唯一引用。因为所有对ref的赋值和取值拿到的都是最终的状态,并不会因为不同的 render 中存在不同的隔离。
  2. 获取 Dom 元素

useLayoutEffect

useLayoutEffect 与 useEffect 使用方式是完全一致的,useLayoutEffect 的区别在于它会在所有的 DOM 变更之后同步调用 effect。

可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前, useLayoutEffect 内部的更新计划将被同步刷新。

[还是得阅读源码]

相关推荐
学不会•1 小时前
css数据不固定情况下,循环加不同背景颜色
前端·javascript·html
EasyNTS2 小时前
H.264/H.265播放器EasyPlayer.js视频流媒体播放器关于websocket1006的异常断连
javascript·h.265·h.264
活宝小娜3 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点3 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow3 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o3 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
刚刚好ā4 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
沉默璇年6 小时前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder6 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
会发光的猪。6 小时前
css使用弹性盒,让每个子元素平均等分父元素的4/1大小
前端·javascript·vue.js