简介
React Hooks 是 React 16.7.0-alpha
版本推出的新特性,它主要目的是为了解决状态共享的问题。是继 render-props 和 higher-order components 之后的第三种状态共享方案,不会产生 JSX 嵌套地狱问题。
React Hooks 带来的好处不仅是 “更 FP,更新粒度更细,代码更清晰”,还有如下三个特性:
- 多个状态不会产生嵌套,写法还是平铺的(renderProps 可以通过 compose 解决,可不但使用略为繁琐,而且因为强制封装一个新对象而增加了实体数量)。
- Hooks 可以引用其他 Hooks。
- 更容易将组件的 UI 与状态分离。
在react-native的0.59.0中,即可支持react hooks的写法。
使用react hooks创建组件
在react native中创建一个组件大概如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| export default class App extends React.Component{ constructor(props) { super(props); this.state = { number: 0, }; }
componentDidMount() { doSomethingA(); } componentWillUnMount() { doSomethingB(); } componentWillReceiveProps(nextProps: Props) { doSomethingC(); } render() { return ( <View> <Text onPress={() => this.setState({ numer: this.state.number + 1 })}> {this.state.number} </Text> </View> ); } }
|
而使用react hooks
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import { useState, useEffect } from 'react'; const App = () => { const [number, setNumber] = useState(0); useEffect(() => { doSomethingA(); return () => { doSomethingB(); } }, []); useEffect(() => { doSomethingC(); }, [number]); return ( <View> <Text onPress={() => setNumber(number + 1)}> {number} </Text> </View> ); }
|
由上述例子可见,使用了react hooks之后,组件由class变成了function。变得更加的轻量级,尤其是在创建无状态组件的时候,使用hooks更加具有优势,代码量减少。
Hooks API Reference
useState
1 2
| import { useState } from 'react'; const [state, setState] = useState(initialState);
|
useState是可以看作是state与setState的替换,它返回有状态值,以及更新它的函数。在初始渲染期间,返回的状态(状态)与作为第一个参数(initialState)传递的值相同。而setState函数用于更新状态。 它接受一个新的状态值并将组件重新渲染。
在后续重新渲染期间,useState返回的第一个值将始终是应用更新后的最新状态。
useEffect
1 2
| import { useEffect } from 'react'; useEffect(didUpdate);
|
useEffect 的代码既会在初始化时候执行,也会在后续每次 rerender 时执行,而返回值在析构时执行。那么他就可以用来代替componentDidMount、componentWillReceiveProps以及componentWillUnmount三个生命周期。而且还支持第二个值来指定某些值作为useEffect的触发条件。
1 2 3 4 5 6 7
| useEffect(() => { const subscription = props.source.subscribe(); return () => { subscription.unsubscribe(); }; }, []);
|
useContext
1
| const value = useContext(MyContext);
|
接受上下文对象(从React.createContext返回的值)并返回该上下文的当前上下文值。 当前上下文值由树中调用组件上方最近的<MyContext.Provider>的值prop确定。
当组件上方最近的<MyContext.Provider>更新时,此Hook将触发重新呈现,并将最新的上下文值传递给该MyContext提供程序。
useContext的参数必须是上下文对象本身
useReducer
可以使用这个hook来实现一个redux机制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import { useReducer } from 'react';
function init(initialCount) { return {count: initialCount}; }
function reducer(state, action) { switch (action.type) { case 'increment': return {count: state.count + 1}; case 'decrement': return {count: state.count - 1}; case 'reset': return init(action.payload); default: throw new Error(); } }
export default function App() { const [state, dispatch] = useReducer( reducer, {count: 0}, ); return ( <View style={styles.container}> <Text>Count: {state.count}</Text> <Text onPress={() => dispatch({type: 'increment'})}>+</Text> <Text onPress={() => dispatch({type: 'decrement'})}>-</Text> <Text onPress={() => dispatch({type: 'reset', payload: 0})}> Reset </Text> </View> ); }
|
其它Hooks
除了以上提及的hooks,react还内置了其它的hooks,详情请参考Hooks API Reference
参考链接