React Hooks

Hooks 简介

React Hooks 是用函数的形式代替原来继承类的形式,并使用预函数的形式管理state

代码对比

现在我们来写一个点击添加一的组件
点击+1

  • 原始写法👇
import React, { Component } from 'react';

class Example extends Component {
   constructor(props) {
       super(props);
       this.state = { count:0 }
   }
   render() { 
       return (
           <div>
               <p>You clicked {this.state.count} times</p>
               <button onClick={this.addCount.bind(this)}>Chlick me</button>
           </div>
       );
   }
   addCount(){
       this.setState({count:this.state.count+1})
   }
}

export default Example;
  • Hooks 写法
import React, { useState } from 'react';
function Example(){
    const [ count , setCount ] = useState(0);
    return (
        <div>
            <p>You clicked {count} times</p>
            <button onClick={()=>{setCount(count+1)}}>click me</button>
        </div>
    )
}
export default Example;

useState介绍

现在我们从三个方面来看useState的用法,分别是声明、读取、使用(修改)

声明

const [count , setCount] = useState(0)
这种方法是用了ES6中数组的解构,取到了useState(0)的第0、1位
意思是声明了一个状态变量count,并把它的初始值设为0,同时提供了一个setCount来改变count值的方法函数

读取

<p>You clicked {count} times</p>
读取和react之前的类函数读取是一样的,想在jsx里使用,使用{}就可以

修改

<button onClick={()=>{setCount(count+1)}}>click me</button>
直接调用setCount函数,这个函数接收的参数是修改过的新状态值.

useEffect代替常用的生命周期函数

在用Class制作组件时,经常会用生命周期函数来处理一些额外的事情.在React Hooks 中也需要这种类似的生命周期函数

用Class的方法为计数器增加生命周期函数

先用原始的方法把计数器的Demo增加两个生命周期函数componentDidMountconmponentDidUpdate.组件第一次渲染和更新时调用.

import React, { Component } from 'react';

class Example3 extends Component {
    constructor(props) {
        super(props);
        this.state = { count:0 }
    }


    componentDidMount(){
        console.log(`ComponentDidMount=>You clicked ${this.state.count} times`)
    }
    componentDidUpdate(){
        console.log(`componentDidUpdate=>You clicked ${this.state.count} times`)
    }

    render() { 
        return (
            <div>
                <p>You clicked {this.state.count} times</p>
                <button onClick={this.addCount.bind(this)}>Chlick me</button>
            </div>
        );
    }
    addCount(){
        this.setState({count:this.state.count+1})
    }
}

export default Example3;

用useEffect函数来代替生命周期函数

代码如下👇 记得要引入useEffect

import React, { useState , useEffect } from 'react';
function Example(){
    const [ count , setCount ] = useState(0);
    //---关键代码---------start-------
    useEffect(()=>{
        console.log(`useEffect=>You clicked ${count} times`)
    })
    //---关键代码---------end-------

    return (
        <div>
            <p>You clicked {count} times</p>
            <button onClick={()=>{setCount(count+1)}}>click me</button>
        </div>
    )
}
export default Example;

注意点

  1. React首次渲染和之后的每次都会调用useEffect函数,而在类函数中我们需要调用两个生命周期函数进行渲染
  2. useEffect中函数是异步执行的

useEffects实现componentWillUnmount生命周期函数

在上面点击添加的例子上增加两个router进行跳转
在两个页面的函数中分别写一个useEffect

export default function Example4() {
  const [count, setCount] = useState(0)

  function Index() {
    useEffect(() => {
      console.log('index页面来了')
    })
    return <h2>JSPang.com</h2>
  }

  function List() {
    useEffect(() => {
      console.log('list页面来了')
    })
    return <h2>List-Page</h2>
  }

  return (
    <div>
      <p>You clicked {count} times</p>
      <button
        onClick={() => {
          setCount(count + 1)
        }}
      >
        click me
      </button>

      <Router>
        <ul>
          <li>
            <Link to="/">首页</Link>
          </li>
          <li>
            <Link to="/list/">列表</Link>
          </li>
        </ul>
        <Route path="/" exact component={Index} />
        <Route path="/list/" component={List} />
      </Router>
    </div>
  )
}

在这里插入图片描述
当点击Link进入任意组件的时候,在浏览器中都会打印一句话,这时可以用返回一个函数的方法进行解绑,代码如下

function Index() {
    useEffect(()=>{
        console.log('useEffect=>老弟你来了!Index页面')
        return ()=>{
            console.log('老弟,你走了!Index页面')
        }
    })
    return <h2>JSPang.com</h2>;
  }

这时再点击切换的时候确实会出现解绑的函数,但是点击计数器按钮的时候也会出现
其实每次状态发生变化的时候,useEffect都进行了解绑

useEffect的第二个参数

所以到底如何才能实现类似componentWillUnmout的效果呢?
useEffect有第二个参数,它是一个数组.数组中可以写入状态对应的变量,当状态值发生改变的时候才进行解绑,如果传入的值为空数组[]时,就是当组件被销毁时才进行解绑

function Index() {
    useEffect(()=>{
        console.log('useEffect=>老弟你来了!Index页面')
        return ()=>{
            console.log('老弟,你走了!Index页面')
        }
    },[])
    return <h2>JSPang.com</h2>;
}

为了加深了解第二个参数的作用,把计数器代码也加上useEffect和解绑方法,并加入第二个参数为空数组👇

function Index() {
    useEffect(()=>{
        console.log('useEffect=>老弟你来了!Index页面')
        return ()=>{
            console.log('老弟,你走了!Index页面')
        }
    },[])
    return <h2>JSPang.com</h2>;
}

这时候的代码是不能执行解绑副作用的,但是如果想每次count发生变化时,都进行解绑,只需要在第二个参数的数组里加入count变量就可以了,👇

useEffect(()=>{
        console.log(`useEffect=>You clicked ${count} times`)

        return ()=>{
            console.log('====================')
        }
    },[count])

useContext 让父子组件传值更简单

更新了一些,放着,我又来活了…

下载方式:https://pan.quark.cn/s/a4b39357ea24 布线问题(分支限界算法)是计算机科学和电子工程领域中一个广为人知的议题,它主要探讨如何在印刷电路板上定位两个节点间最短的连接路径。 在这一议题中,电路板被构建为一个包含 n×m 个方格的矩阵,每个方格能够被界定为可通行或不可通行,其核心任务是定位从初始点到最终点的最短路径。 分支限界算法是处理布线问题的一种常用策略。 该算法与回溯法有相似之处,但存在差异,分支限界法仅需获取满足约束条件的一个最优路径,并按照广度优先或最小成本优先的原则来探索解空间树。 树 T 被构建为子集树或排列树,在探索过程中,每个节点仅被赋予一次成为扩展节点的机会,且会一次性生成其全部子节点。 针对布线问题的解决,队列式分支限界法可以被采用。 从起始位置 a 出发,将其设定为首个扩展节点,并将与该扩展节点相邻且可通行的方格加入至活跃节点队列中,将这些方格标记为 1,即从起始方格 a 到这些方格的距离为 1。 随后,从活跃节点队列中提取队首节点作为下一个扩展节点,并将与当前扩展节点相邻且未标记的方格标记为 2,随后将这些方格存入活跃节点队列。 这一过程将持续进行,直至算法探测到目标方格 b 或活跃节点队列为空。 在实现上述算法时,必须定义一个类 Position 来表征电路板上方格的位置,其成员 row 和 col 分别指示方格所在的行和列。 在方格位置上,布线能够沿右、下、左、上四个方向展开。 这四个方向的移动分别被记为 0、1、2、3。 下述表格中,offset[i].row 和 offset[i].col(i=0,1,2,3)分别提供了沿这四个方向前进 1 步相对于当前方格的相对位移。 在 Java 编程语言中,可以使用二维数组...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值