React函数组件
函数组件
内容
1.创建方式
2.函数组件没有state怎么办
3.函数组件没有生命周期怎么办
4.自定义hooks函数
函数组件的创建方式
两种形式
1' 声明一个变量等于箭头函数
const Hello = (props) => {
return <div>{props.message}</div>
}
//箭头函数可以缩写
const Hello = props => <div>{props.message}</div>
2' 使用function
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的返回值。
其它
1.当需要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>
</>
}
自定义hook
第1次初始化也算变化(undefined变为0),怎么做到从第2次变化才算变化呢?
思路:使用自定义hook函数
逻辑:useUpdate是如何排除第一次执行函数的呢?
把依赖array(fn,array)
放到它自己的依赖里,只要你的依赖一变就把count+1
一发现count>1
就会执行你的思路
count怎么收集到呢?
如果数组变化我就count+1
import React, { useState, useEffect } from "react"
const useUpdate = (fn, array) => {
const [count, setCount] = useState(0)
useEffect(() => { //如果数组变化了我就+1
setCount(x => x + 1)
}, array)
useEffect(() => {
if (count > 1) {
fn()
}
}, [count])
}
const App = props => {
const [n, setN] = React.useState(0)
const onClick = () => {
setN(n + 1)
}
useUpdate(() => {
console.log("n变了")
}, [n])
return (
<div> {n} <button onClick={onClick}>+1</button> </div>
)
}
export default App
⚠️自定义hook注意事项:
1.使用自定义hook函数名必须以use开头。
React默认组件是使用的大写字母开头,而自定义Hook函数使用的是use开头。
2.n最好从外面传进来。n直接用也可以但是可能会有警告。
模块化,把useUpdate放到单独的文件里。
1.src目录下新建useUpdate.js,拷贝代码
import React, { useState, useEffect } from "react"
const useUpdate = (fn, array) => { //自定义hook函数
const [count, setCount] = useState(0)
useEffect(() => {
setCount(x => x + 1)
}, array)
useEffect(() => {
if (count > 1) {
fn()
}
}, [count])
}
export default useUpdate 导出
2.使用useUpdate组件
import React, { useState, useEffect } from "react"
import useUpdate from "./useUpdate"
const App = props => {
const [n, setN] = React.useState(0)
const onClick = () => {
setN(n + 1)
}
useUpdate(() => {
console.log("n变了")
}, [n])
return (
<div>{n}
<button onClick={onClick}>+1</button>
</div>
)
}
export default App
更多文章,请点击 我的博客
本站所有文章、数据、图片均来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:licqi@yunshuaiweb.com