函数组件的创建方式
const Hello = (props) => {
return <div>{props.message}</div>
}
const Hello = props => <div>{props.message}</div>
function Hello(props){
return <div>{props.message}</div>
}
消除了this
函数组件能代替Class组件吗?
完全可以,但是目前不行,我们要学些新的东西,比如hooks API
函数组件代替Class组件
面临两个问题
1.函数组件没有state
React v16.8.0推出Hooks API
其中的一个API叫做useState可以解决问题
2.函数组件没有生命周期
React v16.8.0推出Hooks API
其中的一个API叫做useEffect可以解决问题
useEffect(函数式编程的专有名词)是专门用来解决生命周期的问题的。
1.函数组件没有state怎么办?
React提供了useState并提供读、写2个API,可以对数据进行读、写操作。
第1个参数是读,第2个参数是写,初始值为0。
需要引入useEffect或者直接React.useEffect
const App = props => {
const [n, setN] = React.useState(0)
const onClick = () => {
setN(n + 1)
}
return (
<div>{n}
<button onClick={onClick}> +1 </button>
</div>
)
}
函数组件模拟生命周期
什么叫生命周期?
当处于某个阶段时会有提醒要不要做什么事(渲染、挂载、更新、卸载)
用useEffect模拟3个重要的生命周期
一.通过useEffect模拟/实现第一次渲染
细节:useEffect默认每次渲染都会调用(只有1个参数),利用第2个参数[]指明只在第1次渲染时调用该函数。
import React, { useEffect } from "react"
//需要引入useEffect或者直接`React.useEffect`
const App = props => {
const [n, setN] = React.useState(0)
const onClick = () => {
setN(n + 1)
}
console.log(n) //每次渲染都会执行
useEffect(() => {
console.log("use effect")
}, [])
return (
<div>{n}
<button onClick={onClick}>+1</button>
</div>
)
}
export default App
二.通过useEffect模拟/实现更新
细节:第2个参数填"要更新的"变量,比如在n更新时执行useEffect
1' 只有1个变量时:
useEffect(() => {
console.log("n变了")
}, [n])
2' 有多个变量时:
useEffect(() => {
console.log("n或者m变了")
}, [n, m])
等价于:
useEffect(() => {
console.log("state变了")
})
不写的意思是,任何一个state变化都会执行useEffect函数
三.通过useEffect模拟/实现组件将死
每次点击hide时打印'Child 销毁了'
逻辑: 在useEffect函数里return另外一个函数,return的函数就是要死的。
import React, { useEffect, useState } from "react"
const App = props => {
//constructor
const [childVisible, setChildVisible] = useState(true) //默认看得见
const hide = () => {
setChildVisible(false)
}
const show = () => {
setChildVisible(true)
}
//return就是render
return (
<div>
//如果是true就隐藏,如果是false就显示
{childVisible ? <button onClick={hide}>hide</button> : <button onClick={show}>show</button>}
//如果是<Child />就显示,否则不显示
{childVisible ? <Child /> : null}
</div>
)
}
const Child = props => {
useEffect(() => {
console.log("渲染或者变化了")
return () => {
console.log('Child 销毁了')
}
})
return ( <div>Child</div> )
}
细节
1.不能这样写:onClick={setChildVisible(false)}
onClick只接收函数,setChildVisible(false)返回值是undefined,undefined赋给onClick,onClick有个屁用,基础不扎实不要瞎写。
2.show是用来做函数名的,不是用来做变量的。
其它生命周期怎么模拟?
\
\
模拟render:函数组件的return就是render,返回值就是render的返回值。 其它 .当需要return复杂逻辑时,return可以直接返回一个函数,将复杂逻辑写在函数里:
注意:x一定要返回div! 在x返回div前可以做任何事情
标签名最好都大写,防止跟原生的标签冲突。
const X = () => {
//const n = 1+1 复杂逻辑
return <div>x</div>
}
const App = props =>{
return X()
}
2.不光return x,我还return另外一个函数,把2个函数拼在一起:
标签名最好都大写,防止跟原生的标签冲突
const X = () => {
const n = 1+1
return <div>x</div>
}
const Y = () => {
const n = 1+1
return <div>y</div>
}
const App = props =>{
return <>
<X></X> <Y></Y>
</>
}