美文网首页
useState, useReducer, useEffect学

useState, useReducer, useEffect学

作者: 郁南 | 来源:发表于2019-10-07 16:26 被阅读0次

    参考文章:链接

    定义常量

    // constent文件
    export const ADD = 'add'
    export const MINUS = 'minus'
    export const TIMES = 'times'
    export const DIVIDE = 'divide'
    

    Reducer

    // reducer文件
    import { ADD, MINUS, TIMES, DIVIDE } from './constent';
    
    
    export const reducer = (state: any, action: any) => {
      switch (action.type) {
        case ADD:
          return {
            ...state,
            count: state.count + 1
          }
          break;
        case MINUS:
          return {
            ...state,
            count: state.count - 1
          }
          break;
        case TIMES:
          return {
            ...state,
            count: state.count * 2
          }
          break;
        case DIVIDE:
          return {
            ...state,
            count: state.count / 2
          }
          break;
    
        default:
          break;
      }
    }
    
    export const addCount = (dispatch: any) => {
      dispatch({
        type: ADD,
      });
    }
    
    export const minusCount = (dispatch: any) => {
      dispatch({
        type: MINUS,
      });
    }
    
    
    export const timesCountAsync = (dispatch: any) => {
      setTimeout(() => {
        dispatch({
          type: TIMES,
        });
      }, 500);
    }
    
    
    export const divideCount = (dispatch: any) => {
      dispatch({
        type: DIVIDE,
      });
    }
    

    使用

    // count文件
    import React, { useState, useReducer, useEffect } from 'react';
    import { connect } from 'dva';
    
    import { reducer, addCount, minusCount, timesCountAsync, divideCount } from './reducers';
    
    const AsyncCount = (props: any) => {
      const [loading, setLoading] = useState(true);
      const [state, setState] = useState(0);
      const [count, setCont] = useState(0);
      /**
       * useEffect()接受两个参数,
       * 第一个参数是你要进行的异步操作,
       * 第二个参数是一个数组,用来给出Effect的依赖项。
       * 只要这个数组发生变化,useEffect()就会执行。
       * 当第二项省略不填时,useEffect()会在每次组件渲染时执行。
       * 只要数组里面的数据有变化,useEffect函数就会再次执行,
       * 并且有多少个元素变化,就会重新执行多少次。
       * 所以为了提高性能,可以写多个useEffect函数避免执行多次相同的操作,
       * 每个useEffect只监听对应的‘state’的改变做处理
       */
      useEffect(() => {
        setLoading(true);
        console.log(loading);// 只会执行一次
        setTimeout(() => {
          setLoading(false);
          console.log(123);// 只会执行一次
        }, 2000);
      }, [state]);// 如果换成count或者包含了count,会执行两次
      useEffect(() => {
        setLoading(true);
        console.log(loading);// 只会执行一次
        setTimeout(() => {
          setLoading(false);
          setCont(props.count);
        }, 2000);
      }, [state]);// 如果换成count或者包含了count,会执行两次
      return <>{loading ? <p>Loading...0</p> : <p>{count}</p>}</>;
    };
    
    const Count = (props: any) => {
      const [state, dispatch] = useReducer(reducer, { count: 0 });
    
      return (
        <>
          <p>{state.count}</p>
          <AsyncCount count={1}>Async</AsyncCount>
          <button onClick={() => addCount(dispatch)}>AddCount</button>
          <br />
          <button onClick={() => minusCount(dispatch)}>MinusCount</button>
          <br />
          <button onClick={() => timesCountAsync(dispatch)}>TimesCount</button>
          <br />
          <button onClick={() => divideCount(dispatch)}>DivideCount</button>
        </>
      );
    };
    
    export default connect((state: any) => {
      return { ...state.foo, ...state.global };
    })(Count);
    

    定义自己的Hooks

    import React, { useState, useEffect } from 'react'
    
    /**
    * 核心思想是利用Hooks的思想与特性,
    * 创建一个use*关键字的组件,并返回一个数组,
    * 最后达到如:const [state, setState] = useState(initState) 的目的。
    */
    const usePerson = (name) => {
    const [loading, setLoading] = useState(true)
    const [person, setPerson] = useState({})
    
      useEffect(() => {
        setLoading(true)
        setTimeout(()=> {
          setLoading(false)
          setPerson({name})
        },2000)
      },[name])
      return [loading,person]
    }
    
    const AsyncPage = ({name}) => {
      const [loading, person] = usePerson(name)
        return (
          <>
            {loading?<p>Loading...</p>:<p>{person.name}</p>}
          </>
        )
      }
    
    const PersonPage = () =>{
      const [state, setState]=useState('')
      const changeName = (name) => {
        setState(name)
      }
      return (
        <>
          <AsyncPage name={state}/>
          <button onClick={() => {changeName('名字1')}}>名字1</button>
          <button onClick={() => {changeName('名字2')}}>名字2</button>
        </>
      )
    }
    
    export default PersonPage 
    

    相关文章

      网友评论

          本文标题:useState, useReducer, useEffect学

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