进阶react.js

2021-09-10  本文已影响0人  又菜又爱分享的小肖

组件生命周期

组件的生命周期有助于理解组件的运行方式,完成更复杂的组件功能、分析组件错误原因等
组件的生命周期: 组件从被创建到挂载到页面中运行,再到组件不在时卸载的过程
生命周期的每个阶段总是伴随着一些方法调用,这些方法就是生命周期的钩子函数
构造函数的作用:为开发人员在不同阶段操作组件提供了实际


image.png
创建时(挂载阶段)
image.png
class App extends React.Component {
  constructor() {
    super()
    console.log(1)
  }
  componentDidMount() {
    console.log(3)
  }
  render() {
    console.log(2)
    return (
      <div>
        啊哈
      </div>
    )
  }
}
image.png
更新时

执行时机:setState()、 forceUpdate()、 组件接收到新的props
说明:以上三者任意一种变化,组件就会重新渲染

image.png
卸载时

执行时机:组件从页面中消失
作用:用来做清理操作


image.png

新版完整生命钩子函数

image.png
getDerivedStateFromProps()

shouldComponentUpdate()

getSnapshotBeforeUpdate()

render-props模式

// 子组件
class Hello extends React.Component {
  state = {
    name: '肖'
  }
  render() {
    return this.props.render(this.state);
  }
}
//父组件
class App extends React.Component {
  render() {
    return (
      <div>
        父组件
        <Hello render={msg => {
          return <p>{msg.name}</p>
        }} />
      </div>
    )
  }
}
children代替render属性
// 子组件
class Hello extends React.Component {
  state = {
    name: '肖'
  }
  render() {
    return this.props.children(this.state);
  }
}
//父组件
class App extends React.Component {
  render() {
    return (
      <div>
        父组件
        <Hello>
          {({ name }) => <p>{name}</p>}
        </Hello>
      </div>
    )
  }
}

高阶组件

function WithMouse(WrappedComponent) {
  class Mouse extends React.Component {
    state = {
      time: new Date().getTime()
    }
    render() {
      return <WrappedComponent {...this.state} />
    }
  }
  return Mouse
}
// 需要加强的组件
const Position = (props) => {
  console.log(props);
  return <p>{props.time}</p>
}

// 传递封装加强
let MousePosition = WithMouse(Position);

//父组件
class App extends React.Component {
  render() {
    return (
      <div>
        <MousePosition></MousePosition>
      </div>
    )
  }
}
设置displayName
传递props

React原理

setState()说明
推荐语法
  add = () => {
    this.setState(({ count }) => {
      return {
        count: count + 1
      }
    })
    console.log(this.state.count); //js是单线程 先执行同步再执行异步
  }
第二个参数
  add = () => {
    this.setState(({ count }) => {
      return {
        count: count + 1
      }
    }, () => {
      console.log('这个回调函数会在状态更新后立即执行')
    })
    console.log(this.state.count); //js是单线程 先执行同步再执行异步
  }

JSX语法的转化过程

组件更新机制

image.png

组件性能优化

减轻state
class Hello extends React.Component {
  // 初始化
  componentDidMount() {
    this.timeID = setInterval(() => {
      console.log(1);
    }, 2000)
  }
  // 卸载 移除计时器
  componentWillUnmount() {
    clearInterval(this.timeID);
  }
  render() {
    return <div>子组件</div>
  }
}

避免不必要的重新渲染

class App extends React.Component {
  state = {
    count: 0
  }
  // 每次点击生成一个随机数
  add = () => {
    this.setState({
      count: Math.floor(Math.random() * 3)
    })
  }

  // 将要更新ui的时候会执行这个钩子函数
  shouldComponentUpdate(nextProps, nextState) {
    // 判断一下当前生成的 值是否与页面的值相等
    if (nextState.count !== this.state.count) {
      console.log('已改变');
      return true
    }
    return false
  }
  render() {
    return (
      <div>
        随机数:{this.state.count} <br />
        <button onClick={this.add}>按钮</button>
      </div>
    )
  }
}

利用props参数来判断是否需要进行更新

class App extends React.Component {
    state = {
        number: 0
    }
    // 点击事件,每次点击生成一个随机数
    hanldeBtn = () => {
        this.setState({
            number: Math.floor(Math.random() * 3)
        })
    }

    render() {
        return (
            <div>
                <NumberBox number={this.state.number} />
                <button onClick={this.hanldeBtn}>生成随机数</button>
            </div>
        )
    }
}
class NumberBox extends React.Component {
    // 将要更新UI的时候会执行这个钩子函数
    shouldComponentUpdate(nextProps, nextState) {
        // 判断一下当前生成的 值是否与页面的值相等
        if (nextProps.number !== this.props.number) {
            return true
        }
        return false
    }
    render() {
        return (
            <h1>随机数:{this.props.number} </h1>
        )
    }
}

纯组件

class App extends React.PureComponent{
  render(){
    return (
      <div>纯组件</div>
    )
  }
}
实现原理
const obj = { name: '肖' };
const newObj = obj;
newObj.name = '哈';
console.log(newObj == obj); //ture

虚拟DOM和Diff算法

本质上就是一个JS对象,用来描述你希望在屏幕上看到的内容


image.png
Diff算法

React路由

现代的前端应用大多数是SPA(单页应用程序),也就是只有一个HTML页面的应用程序。因为它的用户体验更好、对服务器压力更小,所以更受欢迎。为了有效的使用单个页面来管理多页面的功能,前端路由应运而生。

安装
npm install --save react-router-dom
导入
import {BrowserRouter as Router, Route, Link} from 'react-router-dom'
// 导入
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'

// 定义内容
const First = () => {
  return <p>页面一的内容</p>
}

//使用Router组件包裹整个应用
const App = () => {
  return (
    <Router>
      <div>
        {/* 指定路由入口 */}
        <Link to="/first">页面一</Link>

        {/* 指定路由出口 */}
        <Route path="/first" component={First}></Route>
      </div>
    </Router>
  )
}
常用组件说明

路由的执行过程

编程式导航
  this.props.history.push('路由')
默认路由
<Route path="/" component={Home}></Route>

匹配模式

模糊匹配模式
// 定义内容
const First = () => {
  return <p>页面一的内容</p>
}

//使用Router组件包裹整个应用
const App = () => {
  return (
    <Router>
      <div>
        {/* 指定路由入口 */}
        <Link to="/first">页面一</Link>

        {/* 指定路由出口 */}
        {/* 模糊匹配 匹配成功*/}
        <Route path="/" component={First}></Route>
      </div>
    </Router>
  )
}
精准匹配
        {/* 此时,该组件只能匹配pathname="/" 这种情况 */}
        <Route exact path="/" component={First}></Route>
上一篇 下一篇

猜你喜欢

热点阅读