react3.0-组件、组件传值、Context、组件生命周期、路由、匹配模式

react3.0

全局导入的变量名可以自定义,按需导入则是要用规定的变量名

复习组件传值:

父传子,子传父:

review.js

import React from "react"
// 传值要注意this指向问题,解决办法有三个:1.在构造函数里面用bind,2.初始化时使用箭头函数,3.在该函数外面套一层箭头函数
// 父组件
class Person extends React.Component {
    state = {
        msg:'我是父组件的数据'
    }
    render() {
        return (
            <div>hello,早上好呀
                { this.state.msg}
                <Son msg={this.state.msg} />
                { /*info是Child子组件绑定的属性,属性值是父组件的回调函数,用来接收数据*/}
                <Child info={ this.getInfo}/>
            </div>
            
        )
    }
    // 给父组件添加事件,是一个回调函数
    // 接收Child传递过来的数据,并重新修改state中msg的值
    // 参数msg就是子组件传递过来的数据
    getInfo = (msg) => {
        this.setState({
            msg:msg
        })
    }
}
// 父传子
// 子组件
function Son(props) {
    return (
        <div>我是Son子组件,父组件传递过来的数据:{ props.msg}</div>
    )
}


class Child extends React.Component {
    // 给子组件添加状态
    state = {
        msg:'我是子组件Child的数据'
    }
    render() {
        return (
            <div>
                我是Child子组件
                { /*通过触发handle事件,将state中的msg数据传递给父组件*/}
                <button onClick={this.handle}>传值,改变父组件的msg</button>
            </div>
        )
    }
    handle = () => {
        // 通过this.props调用父组件的回调函数
        // info是标签的自定义属性,是一个回调函数,参数是要传递的数据
        this.props.info(this.state.msg)
    }
}

export default Person

index.js


import React from 'react';
import ReactDOM from 'react-dom';
// 子传父,父传子
import Person from "./components/review"

ReactDOM.render(
  <div><Person/></div>,
  document.getElementById('root')
);

兄弟组件之间传值:


import React from 'react';
import ReactDOM from 'react-dom';
// 兄弟组件之间的传值:子传父,父传子相结合,通过自定义属性传值
// 公共组件Hello
class Hello extends React.Component {
  // 公用状态count
  state = {
    count: 0
  }
  render() {
    return (
      <div>
        <Son1 info={ this.state.count}/>
        <Son2 info={ this.getInfo}/>
      </div>
    )
  }
  // 处理count
  getInfo = () => {
    this.setState({
      count:this.state.count+1
    })
  }
}

// Son1组件:显示count
class Son1 extends React.Component {
  render() {
    return (
      <div>
        { this.props.info}
      </div>
    )
  }
}
// Son2组件:操作count
class Son2 extends React.Component {
  render() {
    return (
      <div>
        <button onClick={ this.handle}>+1</button>
      </div>
    )
  }
  handle = () => {
    this.props.info()
  }
}

ReactDOM.render(
  <div><Hello /></div>,
  document.getElementById('root')
);

Context


import React from 'react';
import ReactDOM from 'react-dom';
// Provider:提供数据,Consumer:使用数据
const {Provider,Consumer } =React.createContext()
// 想要给哪个组件传值,就在该组件标签外面加一个Provider标签,该标签的value属性值就是要传递的数据

class Hello extends React.Component {
    state = {
        msg:'我是Provider提供的数据'
    }
    render() {
        return (
            <div>
                <Provider value={this.state.msg}>
                    我是Provider标签
                    <Son />
                </Provider>
                <Provider value="我是一个干饭人,加油,努力干饭">
                    <Child/>
                </Provider>
            </div>
        )
    }
}
// 向使用Provider提供的数据数据
class Son extends React.Component {
    render() {
        return (
            <div>
                <Child />
                <Consumer>
                        {data => { return data}}
                </Consumer>
            </div>
        )
    }
}

class Child extends React.Component {
    render() {
        return (
            <div>
                我是Son组件
                <Consumer>{data => { return data}}</Consumer>
            </div>
        )
    }
}


ReactDOM.render(
  <div><Hello /></div>,
  document.getElementById('root')
);

组件生命周期

组件生命周期:组件从被创建挂载到页面中运行,再到组件不用时卸载的过程;生命周期的每个阶段总是伴随着一些方法调用,这些方法就是生命周期的钩子函数

只有类组件才有生命周期,函数组件没有生命周期

钩子函数的作用:为开发人员在不同阶段操作组件提供了时机

生命周期的三个阶段

1.创建时(挂载阶段)

执行时机:组件创建时(页面加载时)

钩子函数的执行顺序:constructor(){}——>render(){}——>componentDidMount(){}

钩子函数触发时机作用
constructor创建组件时,最先执行1.初始化state;2.为事件处理程序绑定this
render每次组件渲染都会触发渲染UI(注意:不能调用setState())
componentDidMount组件挂载(完成DOM渲染)后1.发送网络请求;2.DOM操作
2.更新时(更新阶段)

执行时机:1.setState();2.forceUpdate();3.组件接收到新的props

说明:以上三者任意一种变化,组件就会重新渲染

执行顺序:render()——>componentDidUpdate()

钩子函数触发时机作用
render每次组件渲染都会触发渲染UI(与挂载阶段是同一render)
componentDidUpdate组件更新(完成DOM渲染后)1.发送网络请求;2.DOM操作 注意:如果要setState()必须放在一个if条件中

如果要发起网络请求,一般是在挂载阶段的componentDidMount()里面执行,因为在更新阶段要有执行时机,才会触发componentDidUpdate()

3.卸载时(卸载阶段)

执行时机:组件从页面中消失

钩子函数触发时机作用
componentWillUnmount组件卸载(从页面中消失)执行清理工作(比如:清理定时器,移除监听事件等)
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            // 计数器
            count: 0
        }
    }
    render() {
        return (
            <div>
                {
                    this.state.count > 5 ? <Line /> : <Counter count={this.state.count }/>
                }
                <button onClick={ this.handle}>+1</button>
            </div>
        )
    }
    // 处理count
    handle = () => {
        this.setState({
            count: this.state.count+1
        })
    }
}
// count>5之后,就显示Line组件
class Line extends React.Component {
    render() {
        return (
            <div>
                <p>豆豆上天了</p>
            </div>
        )
    }
}
// count<=5时,显示的是Counter组件
class Counter extends React.Component {
    // 故而在阶段
    componentDidMount() {
        this.timer = setInterval(() => {
            console.log("计数器正在执行中");
        },1000)
    }
    render() {
        return (
            <div>
                <p>豆豆被打的次数:{ this.props.count}</p>
            </div>
        )
    }
    // 卸载阶段
    // 这个组件不存在了,或者被其他组件替换了,困就触发这个事件
    componentWillUnmount() {
        console.log('豆豆上天了,Counter组件被Line组件替换了,不存在了');
        clearInterval(this.timer)
    }
 }

ReactDOM.render(
    <div><App /></div>,
    document.getElementById('root')
);

React路由

SPA:单页面程序,就是只有一个html页面的应用程序;用户体验更好、对服务器的压力更小,所以更受欢迎。一个组件就是页面

前端路由的功能:让用户从一个视图(页面)导航到另一个视图(页面)

前端路由式一套映射规则,在React中,是URL路径与组件的对应关系

使用React路由就是配置路径和组件(配对)

使用步骤:

1.安装:

yarn add react-router-dom
npm i react-router-dom

2.导入(按需导入)路由的三个核心组件:Router,Route,Link

import {BrowserRouter as Router,Route,Link } from "react-router-dom"

Router是BrowserRouter的别名,按需导入的别名用as实现,解构数据的别名用**😗*实现

3.使用Router组件标签包裹整个应用

4.使用Link组件作为导航菜单(路由入口),相当于一个a标签,要有to属性(类似a标签的href属性),

5.使用Route组件配置路由规则和要战士的组件(路由出口),要有path属性和component,

<Router>
//路由入口
	<Link to="/One">到One组件页面去</Link>
	//路由出口
	<Route path='/One' component={One}></Route>
</Router>
import React from 'react';
import ReactDOM from 'react-dom';
// 按需导入
// BrowserRouter as Router:按需导入BrowserRouter,用as,给它取个别名Router
import { BrowserRouter as Router, Route, Link } from "react-router-dom"
// /One页面
const One = () => {
    return (
        <div>
            我是第一个页面
        </div>
    )
}
// App页面
class App extends React.Component {
    render() {
        return (
            <Router>
                {/* 路由入口 */}
                <Link to="/One">到One组件页面去</Link>
                {/* 路由出口 */}
                <Route path='/One' component={One}></Route>
            </Router>
        )
    }
}


ReactDOM.render(
    <div><App /></div>,
    document.getElementById('root')
);

常用组件说明

Router组件:包裹整个应用,一个React应用只需要使用一次

两种常用Router:HashRouterBrowserRouter

HashRouter:使用URL的哈希值实现(localhost/#/One)

(推荐)BrowserRouter:使用H5的historyAPI实现(localhost:3000/One)

匹配模式

import React from 'react';
import ReactDOM from 'react-dom';
// 按需导入
// BrowserRouter as Router:按需导入BrowserRouter,用as,给它取个别名Router
import { BrowserRouter as Router, Route, Link } from "react-router-dom"
// Login页面
class Login extends React.Component {
    handleLogin = () => {
        // 编程式导航
        // 跳转到某个页面
        this.props.history.push('/home')
    }
    render() {
        return (
            <div>
                我是Login页面
                <button onClick={this.handleLogin}>Home</button>
            </div>
        )
    }
}
// Home页面
// 因为是函数组件,所有没有自己的状态
const Home = props => {
    const handleBack = () => {
        // 编程式导航
        // 退回上一页
        props.history.go(-1)
    }
    return (
        <div>
            <h3>我是Home页面</h3>
            <button onClick={handleBack}>Login</button>
        </div>
    )
}
// 默认显示的页面
const Hello = () => {
    return (
        <div>
            <p>hello</p>
        </div>
    )
}
// App页面,整个应用界面
// 在Router标签里面,不要弄编程式导航,因为需要用到props,可是这个App是一级的,没有组件给它传值,所以编程式导航实现不了
class App extends React.Component {
    render() {
        return (
            <Router>
                <div>
                    {/* 路由入口 ,相当一个a标签*/}
                    {/*模糊匹配: to="/hello/login/home",原意是想去home页面,但是匹配的结果是:三个页面都匹配到了 */}
                    {/*精确匹配: 想要精确匹配到某个页面 ,就在该路由出口Route标签添加exact属性*/}
                    <Link to="/hello/login/home">登录</Link>
                    {/* 路由出口 */}
                    {/* 默认路由 */}
                    <Route exact path='/hello' component={Hello}></Route>
                    <Route exact path='/hello/login' component={Login}></Route>
                    <Route exact path='/hello/login/home' component={Home}></Route>
                </div>
            </Router>
        )
    }
}

ReactDOM.render(
    <div><App /></div>,
    document.getElementById('root')
);

热门文章

暂无图片
编程学习 ·

C语言二分查找详解

二分查找是一种知名度很高的查找算法&#xff0c;在对有序数列进行查找时效率远高于传统的顺序查找。 下面这张动图对比了二者的效率差距。 二分查找的基本思想就是通过把目标数和当前数列的中间数进行比较&#xff0c;从而确定目标数是在中间数的左边还是右边&#xff0c;将查…
暂无图片
编程学习 ·

GMX 命令分类列表

建模和计算操作命令&#xff1a; 1.1 . 创建拓扑与坐标文件 gmx editconf - 编辑模拟盒子以及写入子组(subgroups) gmx protonate - 结构质子化 gmx x2top - 根据坐标生成原始拓扑文件 gmx solvate - 体系溶剂化 gmx insert-molecules - 将分子插入已有空位 gmx genconf - 增加…
暂无图片
编程学习 ·

一文高效回顾研究生课程《数值分析》重点

数值分析这门课的本质就是用离散的已知点去估计整体&#xff0c;就是由黑盒子产生的结果去估计这个黑盒子。在数学里这个黑盒子就是一个函数嘛&#xff0c;这门课会介绍许多方法去利用离散点最大化地逼近这个函数&#xff0c;甚至它的导数、积分&#xff0c;甚至微分方程的解。…
暂无图片
编程学习 ·

在职阿里5年,一个28岁女软测工程师的心声

简单的先说一下&#xff0c;坐标杭州&#xff0c;14届本科毕业&#xff0c;算上年前在阿里巴巴的面试&#xff0c;一共有面试了有6家公司&#xff08;因为不想请假&#xff0c;因此只是每个晚上去其他公司面试&#xff0c;所以面试的公司比较少&#xff09; ​ 编辑切换为居中…
暂无图片
编程学习 ·

字符串左旋c语言

目录 题目&#xff1a; 解题思路&#xff1a; 第一步&#xff1a; 第二步&#xff1a; 第三步&#xff1a; 总代码&#xff1a; 题目&#xff1a; 实现一个函数&#xff0c;可以左旋字符串中的k个字符。 例如&#xff1a; ABCD左旋一个字符得到BCDA ABCD左旋两个字符…
暂无图片
编程学习 ·

设计模式--观察者模式笔记

模式的定义与特点 观察者&#xff08;Observer&#xff09;模式的定义&#xff1a;指多个对象间存在一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式&#xf…
暂无图片
编程学习 ·

睡觉突然身体动不了,什么是睡眠痽痪症

很多朋友可能有这样的体验&#xff0c;睡觉过程中突然意识清醒&#xff0c;身体却动弹不了。这时候感觉非常恐怖&#xff0c;希望旁边有一个人推自己一下。阳光以前也经常会碰到这样的情况&#xff0c;一年有一百多次&#xff0c;那时候很害怕晚上到来&#xff0c;睡觉了就会出…
暂无图片
编程学习 ·

深入理解C++智能指针——浅析MSVC源码

文章目录unique_ptrshared_ptr 与 weak_ptrstd::bad_weak_ptr 异常std::enable_shared_from_thisunique_ptr unique_ptr 是一个只移型别&#xff08;move-only type&#xff0c;只移型别还有std::mutex等&#xff09;。 结合一下工厂模式&#xff0c;看看其基本用法&#xff…
暂无图片
编程学习 ·

@TableField(exist = false)

TableField(exist false) //申明此字段不在数据库存在&#xff0c;但代码中需要用到它&#xff0c;通知Mybatis-plus在做写库操作是忽略它。,.
暂无图片
编程学习 ·

Java Web day15

第十二章文件上传和下载 一、如何实现文件上传 要实现Web开发中的文件上传功能&#xff0c;通常需要完成两步操作&#xff1a;一.是在Web页面中添加上传输入项&#xff1b;二是在Servlet中读取上传文件的数据&#xff0c;并保存到本地硬盘中。 需要使用一个Apache组织提供一个…
暂无图片
编程学习 ·

【51nod 2478】【单调栈】【前缀和】小b接水

小b接水题目解题思路Code51nod 2478 小b接水 题目 输入样例 12 0 1 0 2 1 0 1 3 2 1 2 1输出样例 6解题思路 可以发现最后能拦住水的都是向两边递减高度&#xff08;&#xff1f;&#xff09; 不管两个高积木之间的的积木是怎样乱七八糟的高度&#xff0c;最后能用来装水的…
暂无图片
编程学习 ·

花了大半天写了一个UVC扩展单元调试工具

基于DIRECTSHOW 实现的&#xff0c;用的是MFC VS2019. 详见&#xff1a;http://www.usbzh.com/article/detail-761.html 获取方法 加QQ群:952873936&#xff0c;然后在群文件\USB调试工具&测试软件\UVCXU-V1.0(UVC扩展单元调试工具-USB中文网官方版).exe USB中文网 USB中文…
暂无图片
编程学习 ·

贪心(一):区间问题、Huffman树

区间问题 例题一&#xff1a;区间选点 给定 N 个闭区间 [ai,bi]请你在数轴上选择尽量少的点&#xff0c;使得每个区间内至少包含一个选出的点。 输出选择的点的最小数量。 位于区间端点上的点也算作区间内。 输入格式 第一行包含整数 N&#xff0c;表示区间数。 接下来 …
暂无图片
编程学习 ·

C语言练习实例——费氏数列

目录 题目 解法 输出结果 题目 Fibonacci为1200年代的欧洲数学家&#xff0c;在他的着作中曾经提到&#xff1a;「若有一只免子每个月生一只小免子&#xff0c;一个月后小免子也开始生产。起初只有一只免子&#xff0c;一个月后就有两只免子&#xff0c;二个月后有三只免子…
暂无图片
编程学习 ·

Android开发(2): Android 资源

个人笔记整理 Android 资源 Android中的资源&#xff0c;一般分为两类&#xff1a; 系统内置资源&#xff1a;Android SDK中所提供的已经定义好的资源&#xff0c;用户可以直接拿来使用。 用户自定义资源&#xff1a;用户自己定义或引入的&#xff0c;只适用于当前应用的资源…
暂无图片
编程学习 ·

零基础如何在短时间内拿到算法offer

​算法工程师是利用算法处理事物的职业 算法&#xff08;Algorithm&#xff09;是一系列解决问题的清晰指令&#xff0c;也就是说&#xff0c;能够对一定规范的输入&#xff0c;在有限时间内获得所要求的输出。 如果一个算法有缺陷&#xff0c;或不适合于某个问题&#xff0c;执…
暂无图片
编程学习 ·

人工智能:知识图谱实战总结

人工智能python&#xff0c;NLP&#xff0c;知识图谱&#xff0c;机器学习&#xff0c;深度学习人工智能&#xff1a;知识图谱实战前言一、实体建模工具Protegepython&#xff0c;NLP&#xff0c;知识图谱&#xff0c;机器学习&#xff0c;深度学习 人工智能&#xff1a;知识图…
暂无图片
编程学习 ·

【无标题】

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…