React 函数组件
函数组件的创建方式
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> </> }