useState

useState,让函数组件拥有了维持状态的功能。维持状态是指在函数的多次渲染之间,这个state是可以在函数中间共享的

使用方式

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>{ count }</p>
      <button onClick={() => setCount(count + 1)}>点击</button>
    </div>
  )
}

export default Counter

参数解析

useState(initialState)的参数initialState是state的初始值,可以是任意类型,如字符串、数值、布尔值、对象、数组

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);
  const [visible, setVisible] = useState(false);
  const [store, setStore] = useState({});
  const [list, setList] = useState([]);
  const [name, setName] = useState('xcc');
  
  return ...
}

export default Counter

useState()返回值是一个包含两个元素的数组,第一个值为state的值,为只读的,第二个是用来设置state值的

对比类组件

类组件只有一个state,通过通过对象中的不同属性来表示不同的状态,通过setState来进行更新。函数组件可以创建多个state,用来描述不同状态的值,更加语义化

类组件:

import React from 'react'

class Counter extends Component {
  constructor(props) {
    super(props)
    this.state = {
      count: 0,
      visible: false
    }
  }
 
  componentDidMount() { 
    setState({ count: 1 })
  }

  render() {
    ...
  }
}

export default Counter

函数组件:

import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);
  const [visible, setVisible] = useState(false);
  
  return ...
}

export default Counter

使用时需要注意的点

不要在state中存储可以通过计算得到的值

常见情况:

  1. props中传递过来的值
  2. 存储在cookie、localStorage中的值
  3. 挂载在URL参数上的值

useEffect

useEffect,用来执行一段副作用,副作用是指一段和当前执行结果无关的代码。其中代码的执行是不会影响UI的渲染

使用方式

import React, { useState, useEffect } from 'react'

const WindowSize = () => {
  const [size, setSize] = useState(null)

  useEffect(() => {
    const handleResize = () => {
      ...
    }
    window.addEventListener("resize", handleResize)
    return () => {
      window.removeEventListener("resize", handleResize)
    }
  }, [])

  return (
    ...
  )
}

export default WindowSize

参数解析

useEffect(callback, dependencies)

callback为要执行的函数,dependencies为可选的依赖项数组

几种常见的使用方式:

没有依赖项时,会在每次render后执行

useEffect(() => {})

依赖项为空数组时,会在首次render后执行

useEffect(() => {}, [])

依赖项不为空时,会在首次render后,每次依赖项数组发生改变时执行

useEffect(() => {}, [a,b,c])

组件在卸载时执行

useEffect(() => { return () => {} }, [])

对比类组件

useEffect想比类组件的生命周期,基本可以等价于ComponentDidMount、componentDidUpdate 和 componentWillUnmount这三个方法,但有不是完全相同

类组件

import React from 'react'

class WindowSize extends Component {
  constructor(props) {
    super(props)
    this.state = {
      size: null
    }
  }
 
  componentDidMount() { 
    window.addEventListener("resize", this.handleResize)
  }

  componentWillUnmount() { 
    window.removeEventListener("resize", this.handleResize)
  }

  handleResize = () => {
    ...
  }

  render() {
    ...
  }
}

export default WindowSize

函数组件:

import React, { useState, useEffect } from 'react'

const WindowSize = () => {
  const [size, setSize] = useState(null)

  useEffect(() => {
    const handleResize = () => {
      ...
    }
    // 等价于类组件中的componentDidMount
    window.addEventListener("resize", handleResize)
    // 等价于类组件中的componentWillUnmount
    return () => {
      window.removeEventListener("resize", handleResize)
    }
  }, [])

  return (
    ...
  )
}

export default WindowSize

使用时注意的点

依赖项一定要为回调函数中在使用的变量

import React, { useState, useEffect } from 'react'

const Books = ({ id }) => {
  const [list, setList] = useState([])

  useEffect(() => {
    const getList = async () => {
      const res = await getBookList({ id })
      setList(res.data)
    }
    getList()
  }, [id])

  return ...
}

export defaule Books;

依赖项要为一个常量数组,而不是一个动态数据

useEffect(() => {}, [id])

React会使用浅比较来对比依赖项是否发生改变,因此不要使用对象、数组等作为依赖项

function Todos() {
  // 这里在每次组件执行时创建了一个新数组
  const todos = [{ text: 'Learn hooks.'}];
  useEffect(() => {
    console.log('Todos changed.');
  }, [todos]);
}

原文地址:http://www.cnblogs.com/sk-3/p/16900119.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性