React函数组件

1,431 阅读2分钟

创建方式

const Hello = (props)=>{
    return <div>{props.name}</div>
}

const Hello = props => <div>{props.name}</div>

function Hello(){
    return <div>{props.name}</div>
}
//以上3种写法等价是

函数组件代替class组件

面临问题,函数组件没有state,没有生命周期
  • 没有State
  1. React v16.8推出Hooks API
  2. 其中的一个API叫做useState可以解决问题
  • 没有生命周期
  1. React v16.8推出Hooks API
  2. 其中的一个API叫做useEffect可以解决问题
import React,{useState} from 'react'
const App = ()=>{ //使用箭头函数消除了this
    const [n,setN] = useState(0)
    const onClick = ()=>{
        setN(n+1)
    }
    return (
        <div>
            <span>{n}</span>
            <button onClick={onClick}>add One</button>
        </div>
    )
}

useEffect

  • 模拟componentDidMount,第一次渲染后调用
useEffect(()=>console.log('第一次渲染'),[])
//第二个参数传入一个空数组即可
  • 模拟componentDidUpdate,完成更新后调用
const [n,setN] = React.useState(0)
useEffect(()=>console.log('n变了'),[n])
//第二个参数传入数组[x],数组里的x为state的值
useEffect(()=>console.log('n变了'))
//如果需要实现所有state改后都触发,则不传入第二个参数即可
  • 模拟componentWillUnmount,销毁后调用
const App = () => {
  //消除了this
  const [childVisible, setChildVisible] = useState(true);
  const childShow = () => {
    setChildVisible(true);
  };
  const childHide = () => {
    setChildVisible(false);
  };
  return (
    <>
      <div>
        {childVisible ? (
          <button onClick={childHide}>隐藏</button>
        ) : (
          <button onClick={childShow}>显示</button>
        )}
        {childVisible ? <Child /> : null}
      </div>
    </>
  );
};

const Child = () => {
  useEffect(() => {
    return () => {
      console.log("我死了");
    };
  });
  return <div>hi</div>;
};
//函数返回的函数是销毁时执行,函数本身则在渲染变化之时执行
  • 模拟constructor,初始化时执行
// 声明构造函数Baba,添加实例属性color及原型上的方法say
const App = ()=>{ //消除了this
    const [n,setN] = useState(0)
    const onClick = ()=>{
        setN(n+1)
    } //这里之前的代码相当于constructor
    return (
        <div>
            <span>{n}</span>
            <button onClick={onClick}>add One</button>
        </div>
    )
}
//return前的代码相当于初始化constructor
  • 模拟shouldComponentUpdate,返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。可以在你确认不需要更新组件时使用。
//后面的React.memo和useMemo可以解决
  • 模拟render
//函数组件的返回值就是render的返回值

总结:能用函数组件用函数组件,因为他更简单

自定义Hook之useUpdate

//实现state在刚渲染时不触发的useEffect
const Statistics = () => {
    const [n, setN] = useState(0)

    const onClick = () => {
        setN(n + 1)
    }


    const useUpdate = (fn: any, data: any) => {
        const [a, setA] = useState(0)
        useEffect(() => setA(x => x + 1), [data])
        useEffect(() => { if (a > 1) { fn() } }, [a, fn])
    }
    useUpdate(() => console.log('i run'), n)
    return (
        <>
            这是Statistics组件
            <hr></hr>
            {n}
            <button onClick={onClick}>add ONe</button>
        </>
    )
}