一、创建一个函数组件
const Hello = (props) => {
return <div>{props.message}</div>
}
// 或者这样写
const Hello = props => <div>{props.message}</div>
// 常用自写法
function Hello(props){
return <div>{props.message}</div>
}
函数组件代替类组件
函数组件可以代替类组件,因为函数组件语法更加简单易懂,但是也面临以下两个问题
- 没有state
- 没有生命周期
二、没有state的解决方法
React v16.8.0推出Hooks API,其中的 useState
可以解决这个问题
注意: useState
不可以用 if...else
import React, { useState, useEffect } from "react"
const App = props =>{//消除了this
const [n, setN] = React.useState(0)//数组前面是读,后面是写,叫法无所谓
const onClick = () => {
setN(n+1)
}
return {
<div>
{n},
<button onClick = {onClick}>+1</button>
</div>
}
}
三、没有生命周期的解决方法
React v16.8.0推出Hooks API,其中的 useEffect
可以解决这个问题
默认每次渲染都会调用
import React, { useState, useEffect } from "react"
useEffect(()=>{ console.log('数据更新了') },)
useEffect
接受一个函数作为参数,第二个参数表示什么时候调用它
模拟 componentDidMount
import React, { useState, useEffect } from "react"
useEffect(()=>{ console.log('第一次渲染') },[])
第二个参数的空数组表示只在第一次调用,结果是之后点击按钮更新UI都不会打印,以此模拟componentDidMount
模拟 componentDidUpdate
React.useEffect(()=>{
console.log('n变了')
},[n])
想让哪个数据更新之后,执行代码,就把那个数据放到数组里。只有n变了,才会触发。如果m变了,就不会执行。
React.useEffect(()=>{
console.log('n,m变了')
},[n,m])
数组里也可以接受多个数据
React.useEffect(()=>{
console.log('state变了')
})
如果state里有多个数据,想做到不管哪个数据变化,都执行这个函数,就不写第二个参数。比如有n和m,此时不管是n+1,还是m+1,都会打印
但是 useEffect
在第一次渲染时也会触发。我们在类组件里第一次渲染是不会触发的,只有数据变化了才会执行。
模拟 componentWillUnmount
import React, { useState, useEffect } from "react"
useEffect(()=>{
console.log('第一次渲染')
return ()=>{
console.log('组件要死了')
}
})
return的函数会在销毁时执行,因此需要把组件死之前要做的事情放在return后边
const App=(props)=>{
const [childVisible,setChildVisible]=React.useState(true)
//数组前面是读,后面是写,叫法无所谓
const hide=()=>{
setChildVisible(false)
}
const show=()=>{
setChildVisible(true)
}
return (
<div>
{childVisible? <Child /> : null}
{childVisible? <button onClick={hide}>hide</button> : <button onClick={show}>show</button>}
</div>
)
}
const Child=()=>{
React.useEffect(()=>{
return ()=>{
console.log('child死了');
}
})
return <div>Child</div>
}
当点击hide按钮时,Child消失了,有打印。
如果同时存在多个 useEffect
,会按照出现的顺序执行。
自定义Hook
React.useEffect()
当使用它模拟更新后执行函数时,比如n更新后就做什么事情,它会把第一次渲染也算上。有没有什么方法能让它不算第一次渲染的,只在n真正变化时才执行。
可以自定义一个hook函数,这个函数必须是use开头的
import React, { useState, useEffect } from "react"
const useUpdate = (fn, dep) =>{
const [count, setCount] = useState(0)
useEffect(()=>{
setCount(x=> x + 1)
}, [dep]);//这里的dep就相当于n
useEffect(()=>{
if(count > 1){
fn()
}
}, [count, fn]);
}
useUpdate(()=>{
console.log('变了')
},n)
四. useLayoutEffect
useEffect
会在浏览器对真实的DOM节点渲染完成后,执行。useLayoutEffect
会在把虚拟DOM=>真实DOM后,浏览器绘制之前执行。- 这两个是有时间差的,
useLayoutEffect
总是会比useEffect
先执行 - 不过我们都优先使用
useEffect
。有什么事先让浏览器渲染出来再说,不然影响用户体验。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!