zoukankan      html  css  js  c++  java
  • react-hook

    Hook 在 class 内部是不起作用的。但你可以使用它们来取代 class 。
    Hook 是一个特殊的函数,它可以让你“钩入” React 的特性。例如,useState 是允许你在 React 函数组件中添加 state 的 Hook。
    如果你在编写函数组件并意识到需要向其添加一些 state,以前的做法是必须将其它转化为 class。现在你可以在现有的函数组件中使用 Hook。
    Hook是React 16.8.0版本增加的新特性/新语法,可以让你在函数组件中使用 state 以及其他的 React 特性
    Hook 和现有代码可以同时工作,你可以渐进式地使用他们

    1,State Hook

    (1). State Hook让函数组件也可以有state状态, 并进行状态数据的读写操作
    (2). 语法: const [xxx, setXxx] = React.useState(initValue)
    (3). useState()说明:
    参数: 第一次初始化指定的值在内部作缓存
    返回值: 包含2个元素的数组, 第1个为内部当前状态值, 第2个为更新状态值的函数
    (4). setXxx()2种写法:
    setXxx(newValue): 参数为非函数值, 直接指定新的状态值, 内部用其覆盖原来的状态值
    setXxx(value => newValue): 参数为函数, 接收原本的状态值, 返回新的状态值, 内部用其覆盖原来的状态值

    // 1,调用 useState 方法的时候做了什么?
    // 它定义一个 “state 变量”。我们的变量叫 count, 但是我们可以叫他任何名字,比如 banana。这是一种在函数调用时保存变量的方式 —— useState 是一种新方法,
    // 它与 class 里面的 this.state 提供的功能完全相同。一般来说,在函数退出后变量就会”消失”,而 state 中的变量会被 React 保留。
    
    // 2,useState 需要哪些参数? 
    // useState() 方法里面唯一的参数就是初始 state。不同于 class 的是,我们可以按照需要使用数字或字符串对其进行赋值,而不一定是对象。在示例中,
    // 只需使用数字来记录用户点击次数,所以我们传了 0 作为变量的初始 state。(如果我们想要在 state 中存储两个不同的变量,只需调用 useState() 两次即可。)
    
    // 3,useState 方法的返回值是什么? 
    // 返回值为:当前 state 以及更新 state 的函数。这就是我们写 const [count, setCount] = useState() 的原因。这与 class 里面 this.state.count 和 this.setState 类似,
    // 唯一区别就是你需要成对的获取它们。
    
    import React, { useState } from 'react';
    function Example() {
      // 声明一个叫 "count" 的 state 变量
      const [count, setCount] = useState(0);
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    
    // 例如
    function ExampleWithManyStates() {
      // 声明多个 state 变量
      const [age, setAge] = useState(42);
      const [fruit, setFruit] = useState('banana');
      const [todos, setTodos] = useState([{ text: '学习 Hook' }]);
    
    在以上组件中,我们有局部变量 age,fruit 和 todos,并且我们可以单独更新它们:
      function handleOrangeClick() {
        // 和 this.setState({ fruit: 'orange' }) 类似
        setFruit('orange');
      }
    
    // 你不必使用多个 state 变量。State 变量可以很好地存储对象和数组,因此,你仍然可以将相关数据分为一组。然而,不像 class 中的 this.setState,
    // 更新 state 变量总是替换它而不是合并它。
    
    

    2,Effect Hook

    Effect Hook 可以让你在函数组件中执行副作用操作
    可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。
    在 React 组件中有两种常见副作用操作:需要清除的和不需要清除的。

    (1). Effect Hook 可以让你在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)
    (2). React中的副作用操作:
    发ajax请求数据获取
    设置订阅 / 启动定时器
    手动更改真实DOM
    (3). 语法和说明:
    useEffect(() => {
    // 在此可以执行任何带副作用操作
    return () => { // 在组件卸载前执行
    // 在此做一些收尾工作, 比如清除定时器/取消订阅等
    }
    }, [stateValue]) // 如果指定的是[], 回调函数只会在第一次render()后执行

    (4). 可以把 useEffect Hook 看做如下三个函数的组合
    componentDidMount()
    componentDidUpdate()
    componentWillUnmount()

    //1, 无需清除的 effect
    有时候,我们只想在 React 更新 DOM 之后运行一些额外的代码。比如发送网络请求,手动变更 DOM,记录日志,这些都是常见的无需清除的操作。因为我们在执行完这些操作之后,就可以忽略他们了。
    
    import React, { useState, useEffect } from 'react';
    function Example() {
      const [count, setCount] = useState(0);
      // 类似于componentDidMount and componentDidUpdate:
      useEffect(() => {
        // Update the document title using the browser API
        document.title = `You clicked ${count} times`;
      });
      return (
        <div>
          <p>You clicked {count} times</p>
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    }
    
    //1, useEffect 做了什么? 
    // 通过使用这个 Hook,你可以告诉 React 组件需要在渲染后执行某些操作。React 会保存你传递的函数(我们将它称之为 “effect”),并且在执行 DOM 更新之后调用它。
    // 在这个 effect 中,我们设置了 document 的 title 属性,不过我们也可以执行数据获取或调用其他命令式的 API。
    
    //2, 为什么在组件内部调用 useEffect?
    // 将 useEffect 放在组件内部让我们可以在 effect 中直接访问 count state 变量(或其他 props)。我们不需要特殊的 API 来读取它 —— 它已经保存在函数作用域中。
    // Hook 使用了 JavaScript 的闭包机制,而不用在 JavaScript 已经提供了解决方案的情况下,还引入特定的 React API。
    
    // 3,useEffect 会在每次渲染后都执行吗? 
    // 是的,默认情况下,它在第一次渲染之后和每次更新之后都会执行。(我们稍后会谈到如何控制它。)你可能会更容易接受 effect 发生在“渲染之后”这种概念,
    // 不用再去考虑“挂载”还是“更新”。React 保证了每次运行 effect 的同时,DOM 都已经更新完毕。
    
    // 4,传递给 useEffect 的函数在每次渲染中都会有所不同,这是刻意为之的。
    // 事实上这正是我们可以在 effect 中获取最新的 count 的值,而不用担心其过期的原因。每次我们重新渲染,
    // 都会生成新的 effect,替换掉之前的。某种意义上讲,effect 更像是渲染结果的一部分 —— 每个 effect “属于”一次特定的渲染。
    
    
    // 2,需要清除的 effect
    import React from 'react'
    import ReactDOM from 'react-dom'
    
    function Demo(){
    	const [count,setCount] = React.useState(0)
    	const [name,setName] = React.useState('xiaomin')
    
    	React.useEffect(()=>{   //useEffect这里可以传2个参数,后一个不写,就是页面更新,全部输出,这里会打印@,监测所有的,count改变也会打印
    		console.log(@)				//useEffect页面加载都会打印一次
    	})
    
    // 相当于 componentDidMount
    	React.useEffect(()=>{
    		console.log(@)
    	},[])   //这里加第2个参数[],谁也不监测,只是初始会打印1次  
    
    // 相当于 componentDidUpdate
    	React.useEffect(()=>{
    		console.log(@)
    	},[count])   //这里只监测count变化,且count值变化才更新,否则跳过渲染
    
    // 相当于 componentWillUnmount
    	React.useEffect(()=>{
    		let timer = setInterval(()=>{
    			setCount(count => count+1 )
    		},1000)
    		return ()=>{   //这个返回的部分先加载,相当于componentWillUnmount
    			clearInterval(timer)
    		}
    	},[])   
    
    	//加的回调
    	function add(){
    		//setCount(count+1) //第一种写法
    		setCount(count => count+1 )
    	}
    
    	function change(){
    		setName('jack')
    	}
    
    	//卸载组件的回调
    	function unmount(){
    		ReactDOM.unmountComponentAtNode(document.getElementById('root'))
    	}
    
    	return (
    		<div>
    			<h2>当前求和为:{count} {name}</h2>
    			<button onClick={add}>点我+1</button>
    			<button onClick={change}>点我改名</button>
    			<button onClick={unmount}>卸载组件</button>
    		</div>
    	)
    }
    
    export default Demo
    
    

    3,Ref Hook

    (1). Ref Hook可以在函数组件中存储/查找组件内的标签或任意其它数据
    (2). 语法: const refContainer = useRef()
    (3). 作用:保存标签对象,功能与React.createRef()一样

    import React from 'react'
    import ReactDOM from 'react-dom'
    function Demo(){
    	const myRef = React.useRef()
    
    	//提示输入的回调
    	function show(){
    		alert(myRef.current.value)
    	}
    
    	return (
    		<div>
    			<input type="text" ref={myRef}/>
    			<button onClick={show}>点我提示数据</button>
    		</div>
    	)
    }
    export default Demo
    
    
  • 相关阅读:
    校验输入框输入两位小数
    限制输入框只能输入整数
    npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules
    yum -y wget
    docker 安装mysql
    centos 安装docker
    VirtualBox安装CentOS系统
    Spring Cloud服务保护
    从零开始搭建系统2.8——HDFS安装及配置
    从零开始搭建系统4.3——详细设计
  • 原文地址:https://www.cnblogs.com/xm0328/p/14417218.html
Copyright © 2011-2022 走看看