0
点赞
收藏
分享

微信扫一扫

《React扩展知识一》setState更新状态2种写法/ lazyLoad / Fragment / Context / Hooks

small_Sun 2022-08-10 阅读 40

前言

在这里插入图片描述

文章目录

1. setState

setState更新状态的2种写法

1️⃣ setState(stateChange, [callback])------对象式的setState

  • stateChange为状态改变对象(该对象可以体现出状态的更改)
add = () => {
  // 1.获取原来的count值
  const { count } = this.state
  // 2.更新状态
  this.setState({ count: count + 1 })
  console.log('12行的输出', this.state.count)
}
  • callback是可选的回调函数, 它在状态更新完毕界面也更新后(render调用后)才被调用
add = () => {
  // 1.获取原来的count值
  const { count } = this.state
  // 2.更新状态
  this.setState({ count: count + 1 }, () => {
    console.log(this.state.count)
  })
}

2️⃣ setState(updater, [callback])------函数式的setState

  • updater为返回stateChange对象的函数。
  • updater可以接收到state和props
  • callback是可选的回调函数, 它在状态更新、界面也更新后(render调用后)才被调用。
this.setState((state, props) => {
  console.log(state, props)
  return { count: state.count + 1 }
})

总结

2. lazyLoad

路由组件的lazyLoad懒加载

1️⃣引入lazy函数和Suspense组件

import React, { Component, lazy, Suspense } from 'react';

实现路由的懒加载

2️⃣通过React的lazy函数配合import()函数动态加载路由组件 ===> 路由组件代码会被分开打包

const Home = lazy(() =>
  import('./Home')
)
const About = lazy(() =>
  import('./About')
)

3️⃣通过指定在加载得到路由打包文件前显示一个自定义loading界面

<Suspense fallback={<h1>Loading...</h1>}>
    {/* 注册路由 */}
		<Route path="/about" component={About} />
  	<Route path="/home" component={Home} />
</Suspense>

3. Hooks

上两篇文章着重讲解了React Hooks基础和React Hooks进阶,在此简单概括一下:

React Hook/Hooks是什么?

三个常用的Hook

State Hook

function Demo() {
  // 返回值第1个为内部当前状态值, 第2个为更新状态值的函数(方法)
  const [count, setCount] = React.useState(0)
  const [name, setName] = React.useState('tom')

  // 加的回调
  function add() {
    // setCount(count + 1) //第一种写法
    setCount((count) => {  //第二种写法
      return count + 1
    })
  }

  function change() {
    setName('jack')
  }

  return (
    <div>
      <h2>当前求和为:{count}</h2>
      <h2>我的名字是:{name}</h2>
      <button onClick={add}>点我加1</button>
      <button onClick={change}>点我改名</button>
    </div>
  )
}

Effect Hook

React.useEffect(() => {
  let timer = setInterval(() => {
    setCount(count => count + 1)
  }, 1000)
  return () => {
    //这个返回的函数相当于componentWillUnmount()
      clearInterval(timer)
    }
  //如果不写数组,会监测任何改变(相当于componentDidMount()和componentDidUpdate())
}, [])// 如果指定的是[], 回调函数只会在第一次render()后执行(相当于componentDidMount())

Ref Hook

4. Fragment

作用

使用

Demo组件:

import React, { Component, Fragment } from 'react'

export default class Demo extends Component {
  render() {
    return (
      //Fragment只能拥有key属性
      <Fragment key={1}>
        <input type="text" />
      </Fragment>
	//这种写法也行,但是这种写法不能写key等属性
      //<>
      //<input type="text" />
      //</>
    )
  }
}

App.jsx:

import React, { Component, Fragment } from 'react'
import Demo from './components/5_Fragment'

export default class App extends Component {
  render() {
    return (
      <Fragment>
        <Demo />
      </Fragment>
    )
  }
}

5. Context

使用

const XxxContext = React.createContext()  
<XxxContext.Provider value={数据}>
  子组件
</XxxContext.Provider>
//第一种方式:仅适用于类组件 
static contextType = XxxContext  // 声明接收context
this.context // 读取context中的value数据
//第二种方式: 函数组件与类组件都可以
<XxxContext.Consumer>
  {
  	value => ( // value就是context中的value数据
  	要显示的内容
  	)
	}
</XxxContext.Consumer>

示例

祖组件A想要给孙组件C传递数据: 用户名和年龄

在这里插入图片描述

import React, { Component } from 'react'
import './index.css'

// 创建Context对象
const MyContext = React.createContext()
export default class A extends Component {

  state = { username: 'tom', age: 18 }

  render() {
    const { username, age } = this.state
    return (
      <div className='parent'>
        <h3>我是A组件</h3>
        <h4>我的用户名是:{username}</h4>
        <MyContext.Provider value={{ username, age }}>
          <B />
        </MyContext.Provider>
      </div>
    )
  }
}

class B extends Component {
  render() {
    return (
      <div className='child'>
        <h3>我是B组件</h3>
        <C />
      </div>
    )
  }
}

//孙组件为类组件
class C extends Component {
  // 声明接收context
  static contextType = MyContext
  render() {
    // 打印出后代组件的this显示出后代组件的context
    console.log(this.context)
    return (
      <div className='grand'>
        <h3>我是C组件</h3>
        <h4>我从A组件接收到的用户名是:{this.context.username},年龄是:{this.context.age}</h4>
      </div>
    )
  }
}

//孙组件为函数组件
function C() {
  return (
    <div className='grand'>
      <h3>我是C组件</h3>
      <h4>我从A组件接收到的用户名是:
        <MyContext.Consumer>
          {
            value => {
              return `${value.username},年龄是${value.age}`
            }
          }
        </MyContext.Consumer>
      </h4>
    </div>
  )
}

注意

举报

相关推荐

0 条评论