React 函数组件

46 阅读2分钟

什么是组件

能和其他物品组合起来的物件就叫做组件,在 Vue 中,一个构造选项就可以表示一个组件,而在React 中一个React元素返回的函数就是组件

创建方式

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

2
const Hello = props => <div>{props.message}</div>

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

props的使用

直接读取参数 props.xxx

import React from "react";

export default function App() {
  return (
    <div className="App">
      <Son say="我是儿子"/>
    </div>
  );
}

const Son =(props)=>{
    return(
      <div>
        {props.say}
      </div>
    )
}

useState的使用

函数组件中没有类组件中的state,使用 useState Hooks API, 该 API 返回数组,第一项读,第二项写

import React from "react";

export default function App() {
  return (
    <div className="App">
      <Son/>
    </div>
  );
}

const Son =(props)=>{
  const [n,setN] = React.useState(0);
    return(
      <div>
        {n}
        <button onClick={()=>setN(n+1)}>+1</button>
      </div>
    )
}

setState 注意事项

  • 和类组件相同,要通过 setX(新值)来更新 UI
  • 和类组件不同,没有 this,一律用参数和变量
  • setX 不会自动合并属性,使用 ... 操作符可以合并

事件绑定

<button onClick={()=>{this.add()}>n+1</button>
// 推荐使用

<button onClick={this.add}>n+1</button>
// 不推荐,该 this.add 里的this会变成 window

<button onClick={this.add.bind(this)}>n+1</button>
// 不推荐,虽然解决了 this 问题,但是太麻烦

<button onClick={this.add}>n+1</button>
// this.add=()=>this.setState({n: this.state.n+1}),这样不如直接声明 add

<button onClick={this.add}>n+1</button>
// add=()=>this.setState({n: this.state.n+1}) 最好的写法

useEffect

函数组件中没有类组件中的生命周期,于是就有了 useEffect API 的出现,利用该 API 模拟生命周期

模拟 constructor

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

模拟 shouldComponentUpdate

用 React.memo 和 useMome 可以解决

模拟 render

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

模拟 componentDidMount

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

模拟 componentDidUpdate

useEffect(()=>{
	console.log('任意属性变了') 
})

useEffect(()=>{ 
	console.log('属性n变了') 
},[n])

模拟 componentWillUnmount

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

可以出现多个 useEffect,会按照出现顺序依次执行

自定义 Hook

useEffect(()=>{},[n])属性改变时就会执行函数,包括当 nundefined变为0的时候,因此我们自定义一个除了第一次外,后面变化时,执行函数的 Hook

const useUpdate = (fn,dep)=>{
	const [n,setN] = useState(0)
    useEffect(()=>{
    	setN(x=>x+1)
    },[dep])
    useEffect(()=>{
    	if(n>1){
        	fn()
        }
    },[n,fn])
}

自定义 Hook 一定是以 use 函数名开头的函数