Hook 是 React 16.8 的新增特性
官方文档:https://reactjs.org/docs/hooks-reference.html
useState
[参数名, 改变参数的方法] = useState(参数默认值)
const [clickNum, setClickNum] = useState(0)
`setClickNum(pre=>newValue) pre为改变前的值,需返回新的newValue值`
`setClickNum((clickNum)=>clickNum + 1)`
setClickNum((prevState)=>{ return prevState + 1 })
or
setClickNum(0)
`默认参数如果有需要计算`
const [viewInfo,setViewInfo] = useState(()=>{
let info = '{"name": "lucy"}'
const initViewInfo = JSON.parse(info) // 模拟计算
return initViewInfo
})
const [myInfo, setMyInfo] = useState({name: 'jack',age: 20,sex: '南'})
setMyInfo((prevState)=>{ return { ...prevState, age: 23 } })
useEffect
useEffect(()=>{只在第一次加载时执行该函数},[]) 等价于 componentDidMount
useEffect(()=>{return ()=>{卸载时执行该函数}},[]) 等价于 componentWillUnmount
useEffect(()=>{只要渲染完成,就是执行该函数}) 等价于 componentDidUpdate
useEffect(()=>{只有 param 改变时,渲染完成后执行该函数,param改变前后值一样不会执行该函数},[param])
// 等价于 componentDidMount
let interval = null
useEffect(()=>{
console.log('=========');
interval = setInterval(()=> {
console.log('1秒触发');
}, 1000);
},[])
// 等价于 componentWillUnmount
useEffect(()=>{
return ()=>{
console.log('123');
interval && clearInterval(interval)
}
},[])
// 等价于 componentDidUpdate
useEffect(()=>{
console.log('clickNum changed');
},[clickNum])
useEffect(()=>{
console.log('changed');
})
useEffect(()=>{
// props.type改变渲染以后执行该函数 可以在此进行某些操作
console.log('props.type changed');
//e.g
setClickNum((clickNum)=>clickNum + 1)
},[props.type])
useReducer
// const [state, dispatch] = useReducer(reducer, initState);
// ⚠️例如:在当前方法中dispatch后appProgress可以跟着变
// 但是在外部dispatch改变appProgress,这里并不会跟随变动,可以集成三方库redux通过store.subscribe(() => { useState... })进行操作
const [state, dispatch] = React.useReducer(DownloadInfoReducer, {appProgress: 0});
<AntiRepeatButton style={styles.btn} onPress={()=>{
dispatch({type:'jia'})
}}>
<Text style={styles.btnText}>加</Text>
</AntiRepeatButton>
<AntiRepeatButton style={styles.btn} onPress={()=>{
dispatch({type:'jian'})
}}>
<Text style={styles.btnText}>减</Text>
</AntiRepeatButton>
<Text>appProgress:{state.appProgress}</Text>
// DownloadInfoReducer
const initialState = {
appProgress:0
}
export default (state = initialState, action) => {
switch (action.type) {
case 'jia':
return {
...state,
appProgress:state.appProgress+5
};
case 'jian':
return {
...state,
appProgress: state.appProgress-5
};
default:
return state;
}
}
// 监听其他redux的变化
React.useEffect(() => {
store.subscribe(() => {
let progress = store.getState().apkDownloadInfo.appProgress
if(progress > 0){
setBeginDown(true)
setAppProgress(progress)
}else {
setBeginDown(false)
}
})
return ()=>{
}
}, []);
全部代码比较
import React, { useState, useEffect, useRef } from 'react';
import {
View,
Text,
StyleSheet,
Image,
TouchableOpacity,
TextInput
} from 'react-native';
import {connect} from 'react-redux';
const CustomHookView = (props)=>{
//[参数名, 改变参数的方法] = useState(参数默认值)
const [clickNum, setClickNum] = useState(0)
let textInputRef = null
// 默认参数如果有需要计算
const [viewInfo,setViewInfo] = useState(()=>{
let info = '{"name": "lucy"}'
const initViewInfo = JSON.parse(info) // 模拟计算
return initViewInfo
})
const [myInfo, setMyInfo] = useState({name: 'jack',age: 20,sex: '南'})
const onBtnClick=()=>{
//setClickNum(pre=>newValue) pre为改变前的值,需返回新的newValue值
setClickNum((prevState)=>{ return prevState + 1 })
// or
// setClickNum((clickNum)=>clickNum + 1)
// 修改对象中的某一个值时
setMyInfo((prevState)=>{ return { ...prevState, age: 23 } })
}
const onZeroBtnClick = ()=>{
// setClickNum(需要改变的参数的值)
setClickNum(0)
}
const onDisClick=()=>{
textInputRef.blur()
}
// useEffect(()=>{只要渲染完成,就是执行该函数})
// useEffect(()=>{只在第一次加载时执行该函数},[])
// useEffect(()=>{只有 param 改变时,渲染完成后执行该函数,param改变前后值一样不会执行该函数},[param])
// useEffect(()=>{return ()=>{卸载时执行该函数}},[])
// 等价于 componentDidMount
let interval = null
useEffect(()=>{
console.log('=========');
interval = setInterval(()=> {
console.log('1秒触发');
}, 1000);
},[])
// 等价于 componentWillUnmount
useEffect(()=>{
return ()=>{
console.log('123');
interval && clearInterval(interval)
}
},[])
// 等价于 componentDidUpdate
useEffect(()=>{
console.log('clickNum changed');
},[clickNum])
useEffect(()=>{
console.log('changed');
})
useEffect(()=>{
// props.type改变渲染以后执行该函数 可以在此进行某些操作
console.log('props.type changed');
//e.g
setClickNum((clickNum)=>clickNum + 1)
},[props.type])
return <View style={{
backgroundColor:'#f0f0f6',
justifyContent:'center',
alignItems:'center',
paddingVertical: 30
}}>
<Text>点击按钮次数:{clickNum}</Text>
<Text>来自于父组件的值:{props.type}</Text>
<TouchableOpacity style={{backgroundColor:'yellow',marginTop: 10}} onPress={onBtnClick}>
<Text>点击按钮</Text>
</TouchableOpacity>
<TouchableOpacity style={{backgroundColor:'yellow',marginTop: 10}} onPress={onZeroBtnClick}>
<Text>点击按钮归零</Text>
</TouchableOpacity>
<TextInput ref={ref=>textInputRef = ref} style={{width: 100,height:30,backgroundColor:'red',marginTop: 10}} placeholder={'textInput'}/>
<TouchableOpacity style={{backgroundColor:'yellow',marginTop: 10}} onPress={onDisClick}>
<Text>dis键盘</Text>
</TouchableOpacity>
</View>
}
// 普通组件
class CustomView extends React.Component {
constructor(props) {
super(props);
this.state = {
clickNum:0,
viewInfo:JSON.parse('{"name": "lucy"}')
}
}
componentDidMount() {
console.log('componentDidMount');
}
componentWillUnmount(){
console.log('componentWillUnmount');
}
componentDidUpdate(){
// state 改变调用此方法
console.log('componentDidUpdate');
}
onBtnClick=()=>{
this.setState({
clickNum:this.state.clickNum + 1
})
}
onZeroBtnClick = ()=>{
this.setState({
clickNum: 0
})
}
onDisClick=()=>{
this.textInput.blur()
}
render(){
return <View style={{
backgroundColor:'#f0f0f6',
justifyContent:'center',
alignItems:'center',
paddingVertical: 30
}}>
<Text>点击按钮次数:{this.state.clickNum}</Text>
<TouchableOpacity style={{backgroundColor:'yellow',marginTop: 10}} onPress={this.onBtnClick}>
<Text>点击按钮</Text>
</TouchableOpacity>
<TouchableOpacity style={{backgroundColor:'yellow',marginTop: 10}} onPress={this.onZeroBtnClick}>
<Text>点击按钮归零</Text>
</TouchableOpacity>
<TextInput ref={ref=>this.textInput = ref} style={{width: 100,height:30,backgroundColor:'red',marginTop: 10}} placeholder={'textInput'}/>
<TouchableOpacity style={{backgroundColor:'yellow',marginTop: 10}} onPress={this.onDisClick}>
<Text>dis键盘</Text>
</TouchableOpacity>
</View>
}
}
class HooksTest extends React.Component {
constructor(props) {
super(props);
this.state = {
type: 0
}
}
componentDidMount() {
}
onBtnClick=()=>{
this.setState({
type: this.state.type + 1
})
}
render(){
return <View style={styles.container}>
<Text>普通组件</Text>
<CustomView type={this.state.type} />
<View style={{height: 50}}/>
<Text>函数组件</Text>
<CustomHookView type={this.state.type} />
<Text style={{marginTop: 50}}>主界面</Text>
<TouchableOpacity style={{backgroundColor:'yellow',marginTop: 10}} onPress={this.onBtnClick}>
<Text>点击修改子组件的props</Text>
</TouchableOpacity>
</View>
}
}
const mapStateToProps = state => ({
});
const mapDispatchToProps = dispatch => ({
});
export default connect(mapStateToProps, mapDispatchToProps)(HooksTest);
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ffffff',
},
});
网友评论