【Day 22】React 关於 Hook (2)

关於 Hook 的方法与实作

useState

useState 是 hook 的函数,它接收的参数是状态的初始值(initial state),它会返回一个 Array,第0位是当前的 State 的值,第1位是可以改变 State 的 function

档案位置 src/Example.js:

import React, { useState } from 'react';
function Example() {
  const [ name, setName ] = useState('rainbow')   // 初始值
  const [ sex, setSex ] = useState('女')   // 初始值
  const [ age, setAge ] = useState(0)     // 初始值
  return (
    <div>
      <p>姓名:{name}</p>
      <p>性别:{sex}</p>
      <p>年纪:{age}(不可以点超过24下哈哈)</p>
      <button onClick={()=>{setAge(age+1)}}>增加年纪</button>
    </div>
  )
}
export default Example;

上方这个例子,我们会拆解为 宣告、读取、修改这三方面来说明:
1.先使用 const [ parameter, setParameter ] = useState('ParameterValue')去宣告状态。
这里要注意这方法是 ES6 中的解构赋值,如果不写成解构赋值要改写成:

let _useState = useState(0)
let parameter = _useState[0]
let setParameter = _useState[1]

2.再来在 return 後运用 {paramter} 来读取该 State 的值
3.最後使用{()=>{setParameter(parameterNewValue)}}搭配事件去修改 paramter 的值,关於 setParameter,它所接收的是将要更新的值,然後就交给 React 去进行重新渲染

useEffect

react 会等到 render 完後才去调用 useEffect,所以可以让我们在函数元件中执行副作用的操作,可以把 useEffect 看作 ComponentDidMount、ComponentDidUpdate、ComponentWillUnMount的综合体
这里的副作用(Side Effect)指的是我们需要额外功能来取得或处理资料,像是 fetchData, eventHandling,之前有说一般都会在 ComponentDidMount 时处理

useEffect(callback, array)

  1. Callback: 回调函数,用於处理副作用逻辑

回调函数返回函数,相当於 ComponentWillUnmount

// 在回调函数返回一个函数,则是用於清理,像是 ComponentWillUnmount
useEffect(() => {
  // componentDidMount, componentDidUpdate 在这里执行
  console.log('进入页面')
  return () => {
    // componentWillUnmount 在这里执行
    console.log('离开了')
  }
},[])

// 对应到 React Class Component用法:
componentDidMount() {
  console.log('进入页面')
}
componentWillUnmount() {
  console.log('离开了')
}

回调函数里进行副作用操作(像是请求资料),React 官方推荐在 componentDidMount 里处理

// 在回调函数里请求资料:
useEffect(() => {
  const fetchData = async() => {
    await fetch('data url').then(res => res.json())
  }
}, [])

// 对应到 React Class Component用法:
componentDidMount() {
  const fetchData = async() => {
    await fetch('data url').then(res => res.json())
  }
}
  1. Array: 用於控制与执行,分成不带入、带入[]、带入[parameter]三种

如果没有带入 Array,则每一次更新後都会执行:

// 它在第一次渲染後每次更新都会执行:
useEffect(() => {
  console.log(`你已经点击了 ${count} 次`)
})

// 对应到 React Class Component用法:
componentDidMount() {
  console.log(`你已经点击了 ${count} 次`)
}
componentDidUpdate() {
  console.log(`你已经点击了 ${count} 次`)
}

如果带入[],则只在初次 render 後执行一次:

// 它只在第一次 render 後执行一次:
useEffect(() => {
  console.log(`你已经点击了 ${count} 次`)
},[])

// 对应到 React Class Component用法:
componentDidMount() {
  console.log(`你已经点击了 ${count} 次`)
}

如果带入[parameter],则在 parameter 发生改变後执行:

// 它只在 state 数据发生改变後执行 Effect
useEffect(() => {
  console.log(`你已经点击了 ${count} 次`)
}, [count]) // 只在 count 发生变化後执行

// 对应到 React Class Component用法:
componentDidUpdate(prevProps, prevState) {
  if (prevState.count !== this.state.count) {
    console.log(`你已经点击了 ${count} 次`)
  }
}

开始实作

接下来搭配我们前几天讲的 react-router-dom 来实作看看计数器功能。
档案位置 src/Example.js:

import React, { useState, useEffect } from 'react';
import { BrowserRouter , Route, Link } from 'react-router-dom';

function Index() {
  useEffect(() => {
    // componentDidMount, componentDidUpdate 在这里执行
    console.log('useEffect=> Index页面')
    return () => {
      // componentWillUnmount 在这里执行
      console.log('离开Index页面')
    }
  }, [])
  // 可以试着拿掉 []--------------(1)
  // 会发现每次 点击增加按钮 都会执行 'useEffect=> Index页面' 与 '离开Index页面' 
  return <h2>Rainbow Web</h2>
}

function SecondPage() {
  useEffect(() => {
    console.log('useEffect=> Second页面')
    return () => {
      console.log('离开Second页面')
    }
  }, [])   
  // 可以试着拿掉 []--------------(2)
  // 会发现每次 点击增加按钮 都会执行 'useEffect=> Second页面' 与 '离开Second页面'
  return <h2>Rainbow Sencond Page</h2>
}

function Example() {
  const [count, setCount] = useState(0)
  // 下方这个 useEffect 只在 count 发生变化时执行
  // 可以试着将 [count] 改成 [] --------------(3)
  // 会发现 useEffect 就只会在 render 完後执行一次
  useEffect(() => {
    console.log(`useEffect=> 已经点击了${count}次数`)
    return () => {
      console.log('=========================')
    }
  },[count])
  return (
    <div>
      <p>你已经点击了{ count } 次数</p>
      <button onClick={() => {setCount( count+1 )}}>增加</button>
      <BrowserRouter>
        <ul>
          <li><Link to="/">首页</Link></li>
          <li><Link to="/secondPage/">第二分页</Link></li>
        </ul>
        <Route path="/" exact component={Index} />
        <Route path="/secondPage/" component={SecondPage} />
      </BrowserRouter>
    </div>
  )
}
export default Example;

结论

  • 介绍了 Hook 的方法:useState, useEffect

/images/emoticon/emoticon18.gif 要开始燃烧了~冲刺


<<:  【Day30】Pixi-ParticleContainer+结语

>>:  Notification

Day4- Java语言编译器:javac & 运行工具:java (上)

前言 个人在学习java程序时,一开始对於Java如何编译以及执行编译档这块知识很模糊,如何运作的完...

【设计+切版30天实作】|Day12 - 怎麽让使用者选中您想要他选的Plans设计?

设计大纲 今天要来设计「方案」,外面的网站通常会有3个方案供使用者选择。另外如果要吸引使用者注册的话...

Day16 javascript 创建对象

通过 JavaScript,咱们能够定义并创建自己的物件,创建新物件有两种不同的方法: 1.使用 O...

{DAY9} SQL查询语法1

前言 今天要来练习SQL的查询语法 使用的软件是SQLite Studio 我上的课程是郭耀仁老师在...

# Day 29 Page Migration (四)

文件 原文文件:Page migration 翻译: 监控迁移 ======== 下列事件 (计数器...