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会带开负面影响
- 引入了隐式依赖关系
- 不同的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修改的结果得到最终结果而进行一次页面更新
- react可以管控的地方,是异步批量更新,比如事件函数,生命周期函数,组件内部同步代码
- 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 的作用主要有两个:
- 多次渲染之间保证唯一值的纽带。useRef 会在所有的 render 中保持对返回值的唯一引用。因为所有对ref的赋值和取值拿到的都是最终的状态,并不会因为不同的 render 中存在不同的隔离。
- 获取 Dom 元素
useLayoutEffect
useLayoutEffect 与 useEffect 使用方式是完全一致的,useLayoutEffect 的区别在于它会在所有的 DOM 变更之后同步调用 effect。
可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前, useLayoutEffect 内部的更新计划将被同步刷新。
[还是得阅读源码]