react hook视频观后总结
motivation
" With hooks, we separate code not based on the lifecycle method name but based on what the code is doing " -- Dan Abramov
首先,了解当前react存在的问题
1.avoid wrapper hell
避免包装函数嵌套太深,而Dan并不推荐使用mixins模式 链接
2.huge component
组件太大,学习成本太高,高度集中化无法将细化功能抽离出来
3.confusing classes$*&^!(%%!@
不知道什么时候使用function,什么时候使用class来创建组件
有时在lifecycle内注册完事件后(如定时器),又需要在摧毁阶段手动注销事件
注册监听事件后,又需要在组件变化时手动发布事件
API
import
import React, {useState,useContext,useEffect} from 'react'
useState
代替setState
before
class MyCard extends React.Component {
constructor(props){
super(props);
this.state={
name:'Niko'
};
this.handleNameChange = this.handleNameChange.bind(this);
}
handleNameChange(e){
this.setState({name:e.target.name})
}
render(){
return (
<div>
<input
type="text"
value={this.state.name}
onChange={this.handleNameChange}
/>
</div>
)
}
}
after
function MyCard(){
const [name,setName] = userState('Niko')
return (
<div>
<input
type="text"
value={name}
onChange={setName(e.target.value)}
/>
</div>
)
}
优势:
当存在多个input时,我们需要添加多个state。使用hook可以将input的value
和onChange
这些逻辑抽离
function MyCard (){
const firstName = useFormChange('Niko');
const secondName = useFormChange('Bellic');
return (
<div>
<label>{firstName.value}</label>
<input type="text"
value={firstName.value}
onChange={firstName.onChange}
/>
<br/>
<label>{secondName.value}</label>
<input type="text"
value={secondName.value}
onChange={secondName.onChange}
/>
</div>
)
}
function useFormChange(initialValue){
const [value,setValue] = useState(initialValue);
function handleChange(e){
setValue(e.target.value)
}
return {
value,
onChange:handleChange
}
}
useEffect
随时监听state变化
before
class MyCard extends React.Component {
constructor(props){
super(props);
this.state={
name:'Niko',
};
this.handleNameChange = this.handleNameChange.bind(this)
}
componentDidMount(){
document.title = this.state.name;
}
componentWillUpdate(){
document.title = this.state.name
}
handleNameChange(e){
this.setState({name:e.target.name})
}
render(){
return (
<div>
<input
type="text"
value={this.state.name}
onChange={this.handleNameChange}
/>
</div>
)
}
}
after
function MyCard(){
const [name,setName] = useState('Niko')
useEffect=(()=>{
document.title = name
})
return (
<div>
<input
type="text"
value={name}
onChange={setName(e.target.name)}
/>
</div>
)
}
useEffect
返回值还可以实现componentWillMount
useEffect(
()=>{window.addEventListener('resize',handleSizeChange)}
return ()=>{
window.removeEventListener('resize')
}
)
useContext
其实在更新Context API
就已经提出了hook
这一说法,
所以这里也顺便记下useContext
用法
before
import { ThemeContext } from './context'
class MyCard extends React.Component {
render(){
return (
<ThemeContext.Consumer>
{theme => (
<div className="theme"></div>
)}
</Card.Provider>
)
}
}
after
import { ThemeContext } from './context'
function MyCard(){
const theme = useContext(ThemeContext)
return (
<div className={theme}>
//...
</div>
)
}
useAnimated
React Native Animated Hook 封装
"react": "16.8.3",
"react-native": "0.59.5"
import React,{useEffect,useRef} from 'react'
import {
View,
Animated,
Easing
} from "react-native";
export default function(){
const [animatedValue] = useAnimate({
initialValue:0,
animate:animate
});
function animate(){
Animated.loop(
Animated.timing(
animatedValue,
{
toValue: 1,
duration: 350,
easing: Easing.linear
}
)
).start();
}
const rotate= {
transform: [
{
rotate: animatedValue.interpolate({
inputRange: [0, 0.2,0.5,0.8,1],
outputRange: ["0deg","-4deg","0deg","3deg","0deg"]
})
}
]
};
return (
<View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
<Animated.View style={[rotate,{width:40,height:40,backgroundColor:'blue'}]}/>
</View>
)
}
/**
* @configure initialValue
* @configure animate : Function.apply(this, Array:configure)
* **/
function useAnimate(configure){
const useAnimatedValue = (initialValue) => {
const ref = useRef(new Animated.Value(initialValue));
return ref.current
};
const animatedValue = useAnimatedValue(configure.initialValue);
useEffect(()=>{
configure.animate.apply(this,arguments);
});
return [
animatedValue
]
}
最后
建议观看视频,食用更加
网友评论