React中的函数组件详解

1. 创建方式

 //  写法一
const Hello = (props) => {      
    return <div>{props.message}</div>
}

 //  写法二
const Hello = props => <div>{props.message}</div>  

// 写法三
function Hello(props) {
    return <div>{props.message}</div>
}

2. 函数组件代替类组件

面临的问题

  • 函数组件没有state => React v16.8.0推出Hooks API,其中的一个API叫做useState可以解决问题
  • 函数组件没有生命周期 => React v16.8.0推出Hooks API,其中的一个API叫做useEffect可以解决问题

我们对比一下两种组件实现 n + 1 的例子

类组件

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            n: 0
        }
    }

    addNum = () => {
        this.setState({n: this.state.n + 1})
    }

    render() {
        return (
            <div className='App'>
                <span>n:{this.state.n}</span>
                <button onClick={this.addNum}>n+1</button>
            </div>
        )
    }
}

函数组件

const App = props => {
    const [n,setN] = React.useState(0)
    function addNum(){
        setN(n + 1)
    }
    return (
        <div className='App'>
            {n}
            <button onClick={addNum}>+1</button>
        </div>
    )
}

相比之下函数组件更为简洁一些

使用 useEffect 解决生命周期问题

  1. 模拟 componentDidMount 首次渲染

    useEffect(() => { // 模拟componentDidMount 首次渲染
    console.log(‘use effect’)
    },[]) // 空数组必须写

  2. 模拟 componentDidUpdate

    const [n, setN] = React.useState(0)
    useEffect(() => { // 模拟 componentDidUpdate
    console.log(‘n 变化了’)
    },[n]) // 数组里面可以写多个参数表示监听多个变量

    useEffect(() => { // 模拟 componentDidUpdate
    console.log(‘任意属性变更了’)
    }) // 不写数组表示监听所有 useState 的变量
    // 但是这样在第一次渲染时也会触发函数的执行
    解决方法使用自定义Hook 见下一标题

    扫描二维码关注公众号,回复: 14429410 查看本文章
  3. 模拟componentWillUnmount

    useEffect(() => {
    return () => {
    console.log(‘Child 销毁了’)
    }
    }) // 返回一个函数 在销毁时执行

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

  5. shouldComponentUpdate
    后面的 React.memo和useMemo可以解决

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

    // 模拟render里面写逻辑
    const X = (props) => {
    console.log(‘我是要写的逻辑’)
    return (

    逻辑模拟

    )
    }

    const App = props => {
    let [childVisible, setChildVisible] = useState(true)

    const changeVisible = () => {
        setChildVisible(!childVisible)
    }
    
    return (
        <div className='App'>
            {childVisible ? <button onClick={changeVisible}>{childVisible}</button> :
                <button onClick={changeVisible}>hide</button>}
            {/*{childVisible ? <Child/> : null}*/}
            <Child/>
            <X/>     
        </div>
    )
    

    } // 一个函数便是一个组件

3. 自定义 Hook 之 useUpdate
解决上面 n 值初次渲染就执行的问题

const App = props => {
    const [n, setN] = useState(0)
    const onClick = () => {
        setN(n + 1)
    }
    const [nUpdateCount, setNUpdateCount] = useState(0)
    useEffect(() => {    // 初次渲染就执行 + 1
        setNUpdateCount(nUpdateCount + 1)
    }, [n])
    useEffect(() => {    // 初次渲染就执行 判断是否大于1 
        if(nUpdateCount > 1){
            console.log('n变了')
        }
    },[nUpdateCount])
    return (
        <div className='App'>
            n值变成了:{n}
            <button onClick={onClick}>n+1</button>
        </div>
    )
}
//  通过使用两次 useEffect 第一个触发第二个 useEffect 函数计数,大于0便是n值变化了

上面的代码很乱 改进一下

const useX = (fn, dep) => {   // 这就是自定义 Hook 这就可以抽离成别的文件
    const [count, setCount] = useState(0)
    useEffect(() => {
        setCount(x => x + 1)
    }, [dep])
    useEffect(() => {
        if (count > 1) {
            fn()
        }
    }, [count,fn])
}

const App = props => {
    const [n, setN] = useState(0)
    const onClick = () => {
        setN(n + 1)
    }
    useX(() => {
        console.log('n 变化了')
    }, n)
    return (
        <div className='App'>
            n值变成了:{n}
            <button onClick={onClick}>n+1</button>
        </div>
    )
}

先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

猜你喜欢

转载自blog.csdn.net/m0_66557301/article/details/126113979