• React 全栈体系(十五)


    第八章 React 扩展

    一、setState

    1. 代码

    /* index.jsx */
    import React, { Component } from 'react'
    
    export default class Demo extends Component {
    
    	state = {count:0}
    
    	add = ()=>{
    		//对象式的setState
    		/* //1.获取原来的count值
    		const {count} = this.state
    		//2.更新状态
    		this.setState({count:count+1},()=>{
    			console.log(this.state.count);
    		})
    		//console.log('12行的输出',this.state.count); //0 */
    
    		//函数式的setState
    		this.setState( state => ({count:state.count+1}))
    	}
    
    	render() {
    		return (
    			<div>
    				<h1>当前求和为:{this.state.count}</h1>
    				<button onClick={this.add}>点我+1</button>
    			</div>
    		)
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    2. 总结

    • setState 更新状态的 2 种写法
    (1). setState(stateChange, [callback])------对象式的setState
         1.stateChange为状态改变对象(该对象可以体现出状态的更改)
         2.callback是可选的回调函数, 它在状态更新完毕、界面也更新后(render调用后)才被调用
    
    (2). setState(updater, [callback])------函数式的setState
         1.updater为返回stateChange对象的函数。
         2.updater可以接收到state和props。
         4.callback是可选的回调函数, 它在状态更新、界面也更新后(render调用后)才被调用。
    总结:
    	1.对象式的setState是函数式的setState的简写方式(语法糖)
    	2.使用原则:
    	(1).如果新状态不依赖于原状态 ===> 使用对象方式
    	(2).如果新状态依赖于原状态 ===> 使用函数方式
    	(3).如果需要在setState()执行后获取最新的状态数据,
    	要在第二个callback函数中读取
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    二、lazyLoad

    1. 代码

    /* index.jsx */
    import React, { Component,lazy,Suspense} from 'react'
    import {NavLink,Route} from 'react-router-dom'
    
    // import Home from './Home'
    // import About from './About'
    
    import Loading from './Loading'
    const Home = lazy(()=> import('./Home') )
    const About = lazy(()=> import('./About'))
    
    export default class Demo extends Component {
    	render() {
    		return (
    			<div>
    				<div className="row">
    					<div className="col-xs-offset-2 col-xs-8">
    						<div className="page-header"><h2>React Router Demo</h2></div>
    					</div>
    				</div>
    				<div className="row">
    					<div className="col-xs-2 col-xs-offset-2">
    						<div className="list-group">
    							{/* 在React中靠路由链接实现切换组件--编写路由链接 */}
    							<NavLink className="list-group-item" to="/about">About</NavLink>
    							<NavLink className="list-group-item" to="/home">Home</NavLink>
    						</div>
    					</div>
    					<div className="col-xs-6">
    						<div className="panel">
    							<div className="panel-body">
    								<Suspense fallback={<Loading/>}>
    									{/* 注册路由 */}
    									<Route path="/about" component={About}/>
    									<Route path="/home" component={Home}/>
    								</Suspense>
    							</div>
    						</div>
    					</div>
    				</div>
    			</div>
    		)
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    /* Loading/index.jsx */
    import React, { Component } from 'react'
    
    export default class Loading extends Component {
    	render() {
    		return (
    			<div>
    				<h1 style={{backgroundColor:'gray',color:'orange'}}>Loading....</h1>
    			</div>
    		)
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2. 总结

    //1.通过React的lazy函数配合import()函数动态加载路由组件 ===> 路由组件代码会被分开打包
    const Login = lazy(()=>import('@/pages/Login'))
    
    //2.通过指定在加载得到路由打包文件前显示一个自定义loading界面
    <Suspense fallback={<h1>loading.....</h1>}>
        <Switch>
            <Route path="/xxx" component={Xxxx}/>
            <Redirect to="/login"/>
        </Switch>
    </Suspense>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    三、Hooks

    1. React Hook/Hooks 是什么?

    • Hook 是 React 16.8.0 版本增加的新特性/新语法
    • 可以让你在函数组件中使用 state 以及其他的 React 特性

    2. 三个常用的 Hook

    • State Hook: React.useState()
    • Effect Hook: React.useEffect()
    • Ref Hook: React.useRef()

    3. stateHook

    请添加图片描述
    请添加图片描述

    3.1 代码
    /* src/App.jsx */
    import React from "react";
    
    function Demo() {
    
      const [count, setCount] = React.useState(0);
      const [name, setName] = React.useState("tom");
    
      //加的回调
      function add() {
        //setCount(count+1) //第一种写法
        setCount((count) => count + 1);
      }
    
      function changeName() {
        setName("jack");
      }
    
      return (
        <div>
          <h2>当前求和为:{count}</h2>
          <h2>我的名字是:{name}</h2>
          <button onClick={add}>点我+1</button>
          <button onClick={changeName}>点我改名</button>
        </div>
      );
    }
    
    export default Demo;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    3.2 总结
    (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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4. EffectHook

    4.1 代码
    /* src/App.jsx */
    import React from "react";
    import ReactDOM from "react-dom";
    
    function Demo() {
    
      const [count, setCount] = React.useState(0);
    
      React.useEffect(() => {
        let timer = setInterval(() => {
          setCount((count) => count + 1);
        }, 1000);
        return () => {
          clearInterval(timer);
        };
      });
    
      //加的回调
      function add() {
        //setCount(count+1) //第一种写法
        setCount((count) => count + 1);
      }
    
      //卸载组件的回调
      function unmount() {
        ReactDOM.unmountComponentAtNode(document.getElementById("root"));
      }
    
      return (
        <div>
          <h2>当前求和为:{count}</h2>
          <button onClick={add}>点我+1</button>
          <button onClick={unmount}>卸载组件</button>
        </div>
      );
    }
    
    export default Demo;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    4.2 总结
    (1). Effect Hook 可以让你在函数组件中执行副作用操作(用于模拟类组件中的生命周期钩子)
    (2). React中的副作用操作:
            发ajax请求数据获取
            设置订阅 / 启动定时器
            手动更改真实DOM
    (3). 语法和说明:
            useEffect(() => {
              // 在此可以执行任何带副作用操作
              return () => { // 在组件卸载前执行
                // 在此做一些收尾工作, 比如清除定时器/取消订阅等
              }
            }, [stateValue]) // 如果指定的是[], 回调函数只会在第一次render()后执行
    
    (4). 可以把 useEffect Hook 看做如下三个函数的组合
            componentDidMount()
            componentDidUpdate()
        	componentWillUnmount()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    5. RefHook

    请添加图片描述

    5.1 代码
    /* src/App.jsx */
    import React from "react";
    import ReactDOM from "react-dom";
    
    //类式组件
    /* class Demo extends React.Component {
    
    	state = {count:0}
    
    	myRef = React.createRef()
    
    	add = ()=>{
    		this.setState(state => ({count:state.count+1}))
    	}
    
    	unmount = ()=>{
    		ReactDOM.unmountComponentAtNode(document.getElementById('root'))
    	}
    
    	show = ()=>{
    		alert(this.myRef.current.value)
    	}
    
    	componentDidMount(){
    		this.timer = setInterval(()=>{
    			this.setState( state => ({count:state.count+1}))
    		},1000)
    	}
    
    	componentWillUnmount(){
    		clearInterval(this.timer)
    	}
    
    	render() {
    		return (
    			

    当前求和为{this.state.count}

    ) } } */
    function Demo() { //console.log('Demo'); const [count, setCount] = React.useState(0); const myRef = React.useRef(); React.useEffect(() => { let timer = setInterval(() => { setCount((count) => count + 1); }, 1000); return () => { clearInterval(timer); }; }, []); //加的回调 function add() { //setCount(count+1) //第一种写法 setCount((count) => count + 1); } //提示输入的回调 function show() { alert(myRef.current.value); } //卸载组件的回调 function unmount() { ReactDOM.unmountComponentAtNode(document.getElementById("root")); } return ( <div> <input type="text" ref={myRef} /> <h2>当前求和为:{count}</h2> <button onClick={add}>点我+1</button> <button onClick={unmount}>卸载组件</button> <button onClick={show}>点我提示数据</button> </div> ); } export default Demo;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    5.2 总结
    (1). Ref Hook可以在函数组件中存储/查找组件内的标签或任意其它数据
    (2). 语法: const refContainer = useRef()
    (3). 作用:保存标签对象,功能与React.createRef()一样
    
    • 1
    • 2
    • 3

    四、Fragment

    1. 使用

    <Fragment><Fragment>
    <></>
    
    • 1
    • 2

    2. 作用

    可以不用必须有一个真实的 DOM 根标签了

    3. 代码

    /* index.jsx */
    import React, { Component,Fragment } from 'react'
    
    export default class Demo extends Component {
    	render() {
    		return (
    			<Fragment key={1}>
    				<input type="text"/>
    				<input type="text"/>
    			</Fragment>
    		)
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    Kotlin 乘法、我怎么越乘越小?
    HTML5+CSS3小实例:悬停放大图片的旅游画廊
    OpenCV 实现霍夫圆变换
    代码风格改善
    指令keep-alive
    编写HTTP协议代理的一些知识(源码)
    03-HTML
    影像组学提取特征,图像标签尺寸不一致
    需要用来做3D家具展示的软件哪个网站更专业?
    区块链加密虚拟货币交易平台安全解决方案
  • 原文地址:https://blog.csdn.net/sgsgkxkx/article/details/133280766