React hooks-useState、useEffect、u

作者: 精神病患者link常 | 来源:发表于2020-07-03 17:15 被阅读0次

    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',
        },
    });
    
    

    相关文章

      网友评论

        本文标题:React hooks-useState、useEffect、u

        本文链接:https://www.haomeiwen.com/subject/nzerqktx.html