React 函数组件详解

133 阅读3分钟

函数组件创建方式

使用箭头函数
const Hello = (props) => {
  return <div>{props.message}</div>
}

简写箭头函数
const Hello = props => <div>{props.message}</div>

function函数
function Hello(props){
  return <div>{props.message}</div>
}

函数组件和类组件对比

类组件
class App extends React.Component{
  constructor(props){
    super(props);
    this.state = { n: 1};
  }
  onClick = () =>{
    this.setState(state =>({n: state.n + 1}));
  };
  render(){
    return(
      <div>
        {this.state.n}
        <button onclick={this.onClick}+1</button>
      </div>
      )
   }
}

函数组件
import React, {useState} from "react";
const App = props =>{
  const [n, setN] = useState(0);
  const onClick = () =>{
    setN(n + 1);
  }
  return(
    <div>
        {n}
        <button onclick={onClick}+1</button>
    </div>
  );
}
export default App;

函数组件没有state

使用useState,是React提供的,先从React上引入,下面函数组件就直接使用useState
const [n, setN] = useState(0);
把初始值写在useState里,读是n,写是steN

函数组件没有生命周期

使用API useEffect 模拟生命周期

模拟comPonentDidMount

useEffect(()=> {console.log('第一次渲染')},[])

import React, {useState, useEffect} from "react";  //先从react引入useEffect
const App = props =>{
  const [n, setN] = useState(0);
  const onClick = () =>{
    setN(n + 1);
  }
  useEffect(()=> {
    console.log('第一次渲染')
  },[])                                            //第二个参数表示指明在什么情况下调用函数
                                                   //只在第一次渲染时调用,填空数组
  return(
    <div>
        {n}
        <button onclick={onClick}+1</button>
    </div>
  );
}
export default App;

模拟comPonentDidUpdate

useEffect(()=>{ console.log(' 任意属性变了')})
如果有多个state变化,就直接不写数组或者把多个state写全,任何东西变化就执行函数
useEffect(()=>{ console.log('n变了')}, [n])
n表示,要在什么东西更新时执行函数,n更新就执行函数,

模拟comPonentWillUnmount

useEffect(()=>{
  console.log('第一次渲染')
  return ()=>{
    console.log('组件要死了')
  }
})

import React, {useState, useEffect} from "react";
const App = props =>{
  const [childVisble, setChildVisible] = useState(true)
  const hide = ()=>{
    setChildVisible(false)
  }
  const show = ()=>{
    setChildVisible(true)
  }
  return(
    <div>
      {childVisible ?
        <button onClick={hide}>hide</button> :
          <button onClick={show}>show</button>}
      {childVisible ? <Child/> : null}
    </div>
  )
}

const Child = (props) =>{
  useEffect(()=>{
    console.log('渲染或者变化了')
    return ()=>{           //函数返回的函数,是在销毁时执行的函数,函数本身在渲染和变化时执行
      console.log('Child销毁了')
    }
  })
    return(
      <div>Child</div>
  )
}
export default App;

return 里写的函数,函数可以直接当标签用

import React, {useState, useEffect} from "react";

const x = ()=>{
  const n = 1+1
  return <div>x</div>
}
const y = ()=>{
  const n = 1+1
  return <div>y</div>
}
const App = props =>{
  const [childVisble, setChildVisible] = useState(true)
  const hide = ()=>{
    setChildVisible(false)
  }
  const show = ()=>{
    setChildVisible(true)
  }
  return <>
      <x></x><y></y>
    </>
}

constructor

函数组件执行的时候,就相当于constructor

const [childVisble, setChildVisible] = useState(true)
  const hide = ()=>{
    setChildVisible(false)
  }
  const show = ()=>{
    setChildVisible(true)
  }
这部分相当于constructor

render

函数组件的返回值就是render的返回值

return(
    <div>
      {childVisible ?
        <button onClick={hide}>hide</button> :
          <button onClick={show}>show</button>}
      {childVisible ? <Child/> : null}
    </div>
  )

自定义 Hook,实现useUpdate

const useUpdate = (fn, dep) =>{       //dep(你的依赖)只支持一个变量,把单个的dep放到数组里
  const [count, setCount] = useState(0);
  useEffect(() =>{
    setCount(x => x + 1);             //只要你的依赖变了,就把setCount+1
  }, [dep]);                          //把你的依赖放到自己的依赖上
  
  useEffect(() => {
    if(count > 1){                    //一发现count>1 就会执行fn函数
      fn();                           //count第一次赋值的时不会函数执行,之后才会执行函数
    }
  }, [count, fn]);
};
export default useUpdate

import React, {useState, useEffect} from "react";
import useUpdate from "./useUpdate.js";

const App = props =>{
  const [n, setN] = useState(0);
  const onClick = () =>{
    setN(n + 1);
  }
  useUpdate(()=>{                     //useUpdate在n变了时执行函数(排除第一次)
    console.log("变了");
  }, n);

   return(
    <div>
        {n}
        <button onclick={onClick}+1</button>
    </div>
  );
}
export default App;

详细资料点击:React 函数组件