ReactNative Hook
2021-02-05 本文已影响0人
li_礼光
ReactNative Hook
对比iOS, 有点类似于runtime机制. 也有点类似于重写属性的某些方法, 比如把组件看做某个属性, 重写了didSet,didGet,setter,getter方法等等.
useState
useState 是允许你在 React 函数组件中添加 state 的 Hook, 就是在不编写 class 的情况下使用 state 以及其他的 React 特性
import React, { useState } from 'react';
function Example() {
// 声明一个叫 "count" 的 state 变量
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
读取 State
当我们想在 class 中显示当前的 count,我们读取 this.state.count:
<p>You clicked {this.state.count} times</p>
在函数中,我们可以直接用 count:
<p>You clicked {count} times</p>
更新 State
在 class 中,我们需要调用 this.setState() 来更新 count 值:
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
在函数中,我们已经有了 setCount 和 count 变量,所以我们不需要 this:
<button onClick={() => setCount(count + 1)}>
Click me
</button>
useEffect
你可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。
正常的Class形式
class FriendStatus extends React.Component {
constructor(props) {
super(props);
this.state = { isOnline: null };
this.handleStatusChange = this.handleStatusChange.bind(this);
}
componentDidMount() {
ChatAPI.subscribeToFriendStatus(
this.props.friend.id,
this.handleStatusChange
);
}
componentWillUnmount() {
ChatAPI.unsubscribeFromFriendStatus(
this.props.friend.id,
this.handleStatusChange
);
}
handleStatusChange(status) {
this.setState({
isOnline: status.isOnline
});
}
render() {
if (this.state.isOnline === null) {
return 'Loading...';
}
return this.state.isOnline ? 'Online' : 'Offline';
}
}
useEffect hook形式
import React, { useState, useEffect } from 'react';
function FriendStatus(props) {
const [isOnline, setIsOnline] = useState(null);
// Similar to componentDidMount and componentDidUpdate
useEffect(() => {
// 内部方法功能实现相当于在componentDidMount调用了
// ChatAPI.unsubscribeFromFriendStatus
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
// 返回的函数,相当于在componentWillUnmount调用了
// ChatAPI.unsubscribeFromFriendStatus
return function cleanup() {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
if (isOnline === null) {
return 'Loading...';
}
return isOnline ? 'Online' : 'Offline';
}
通过跳过 Effect 进行性能优化
useMemo
简单粗暴来理解的话, 有点类似于Swift中重写某一个属性的didSet方法, 又或者是OC中的KVO, 这里的useMemo方法会影响渲染, 所以不要在这个函数内部执行与渲染无关的操作.
返回一个memoized值, 也就是一个泛型的T. 可以是string, 可以是int, 可以是array....
/**
* `useMemo` will only recompute the memoized value when one of the `deps` has changed.
*
* Usage note: if calling `useMemo` with a referentially stable function,
* also give it as the input in
* the second argument.
*
* ```ts
* function expensive () { ... }
*
* function Component () {
* const expensiveResult = useMemo(expensive, [expensive])
* return ...
* }
* ```
*
* @version 16.8.0
* @see https://reactjs.org/docs/hooks-reference.html#usememo
*/
// allow undefined, but don't make it optional as that is very likely a mistake
function useMemo<T>(factory: () => T, deps: DependencyList | undefined): T;
示例 :
返回一个memoized值 , 最终真实的值是String
image.pnguseCallback
用一个实例, 简单粗暴理解使用场景
类比iPhone里面的照片, 实况照片. 长按会播放, 不按会显示静态图片, 比如状态变化需要1s以上
<TouchableWithoutFeedback onPress={onLongPress}>
<Image>实况照片</Image>
</TouchableWithoutFeedback>
const onLongPress = useCallback(async () => {
if (大于1s) {
播放实况照片
}
}, [长按时长]);
useRef
const refContainer = useRef(initialValue);
useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。