react用法速览

73 阅读3分钟

react是什么?

react是facebook内部创建的用于构建用户界面的javascript框架。

react代码库地址

https://github.com/facebook/react/

react官方文档

https://reactjs.org/

废话不多说,让我们创建一个项目来体验一下react。

创建命令

npx create-react-app my-app

react核心概念

函数组件和类组件

类组件

import React from "react";

export default class ClassSub extends React.Component {
    render() {
        return <h1>Hello, {this.props.name}</h1>;
    }
}

函数组件

export default function FunctionSub(props) {
    return <h1>Hello, {props.name}</h1>;
}

生命周期

生命周期图解链接React Lifecycle Methods diagram,和官网的React.Component – React一样。

import React from "react";

export default class ClassSub extends React.Component {


    constructor(props) {
        super(props);
        this.state={
            count:0
        }
        console.log(1)
    }

    componentDidMount() {
        console.log(3)
    }

    shouldComponentUpdate(nextProps, nextState, nextContext) {
//可以做性能优化
        console.log(4)
        return true;
    }
    getSnapshotBeforeUpdate(prevProps, prevState) {
        console.log(5)
        let snap="react"
        return snap;
    }
    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log(snapshot)
        console.log(6)
    }

    render() {
        console.log(2)
        return <h1 onClick={()=>{this.setState({count:++this.state.count,})}}>Hello, {this.props.name},{this.state.count}</h1>;
    }
}

添加图片注释,不超过 140 字(可选)

函数式组件生命周期

import {useEffect, useState} from "react";

export default function FunctionSub(props) {
    let [count,setCount]=useState(0);
    console.log(1)
    useEffect(()=>{
        console.log(2)
        return ()=>{
            console.log(4)
        }
    },[])
    useEffect(()=>{
        console.log(3)
    })

    return <h1>Hello, {props.name}</h1>;
}

添加图片注释,不超过 140 字(可选)

为什么会打印两次呢?这是react开发环境下的设置,在生产环境不会发生。由此可见,开发环境下,react是把组件渲染又销毁,完整的走了一遍生命周期。类组件下有时触发了打印两次,有时又没有,但是函数式组件刷新页面都能看到打印两次。

以上就是react的基本概念了。看到这里你就算是已经入门了。

自古以来,人们都喜欢偷懒。也可以说是为了提高效率。我们总是希望复用代码的逻辑,而不是cv。

组件复用

从上面的讲解,你大概已经猜到了。react界存在两派人物,一派是忠厚老实的类组件,一派是奸诈狡猾的函数式组件。

现在,老板出题了。我要在组件里拿到鼠标的位置,你们分别用你们的方式实现一下吧。

类组件

类马上想到了解决办法。在类里我可以利用高阶组件,传入一个组件,我改装一下,出厂就可以带上鼠标位置了。

import React from 'react'

export default function mouse(WrappedComponent) {

    return class extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                x:0,
                y:0
            };
            this.getMousePosition=this.getMousePosition.bind(this)
        }

        componentDidMount() {
            document.addEventListener('mousemove',this.getMousePosition)
        }

        componentWillUnmount() {
            document.removeEventListener('mousemove',this.getMousePosition)
        }
        getMousePosition(e){
            this.setState({
                x:e.clientX,
                y:e.clientY
            })
        }

        render() {
            return <WrappedComponent {...this.state} />;
        }
    };
}
import ClassSub from "./ClassSub";
import ClassSub2 from "./ClassSub2";
import mouse from "./high";
let C1 = mouse(ClassSub)
let C2 = mouse(ClassSub2)
function App() {
  return (
    <div>
      <C1/>
      <C2/>
    </div>
  );
}

export default App;

添加图片注释,不超过 140 字(可选)

类做完了。老板一看,满意地点了点头。

函数马上叫到:瞧你那别扭的熊样,这写的是人看的吗?我用hooks实现起来简洁明了。

类气得无话可说。老板高兴的说道:好,我们看看函数到底有啥妙招。

函数组件

import {useEffect, useState} from "react";

export default function useMouse(){
    let [x,setX]= useState(0)
    let [y,setY]= useState(0)
    useEffect(()=>{
        const mouse=(e)=>{
            setX(e.clientX)
            setY(e.clientY)
        }
        document.addEventListener('mousemove',mouse)
        return ()=>{
            document.removeEventListener('mousemove',mouse)
        }
    },[])
    return [x,y]
}

函数很快完成了。的确是比较简单实用。老板随即宣布函数获胜。

总结

函数组件是react 16版本出的新的api。以简洁高效的复用功能,一经推出,就迅速风靡了前端领域。我觉得react好用的原因是可以用js的思维写组件。但是react一直以学习曲线陡峭著称,原因在于react内部处理的复杂性是一时半会难以理解的,以至于无法灵活使用。下次我们来深入react的源码,看看react内部有什么样的巧思和设计。

如果文章对你有帮助,欢迎一键三连。