干巴爹兔的博客 干巴爹兔的博客
首页
  • 前端文章

    • JavaScript
    • HTML
    • Vue
  • 学习笔记

    • JavaScript教程
    • React学习笔记
    • Electron学习笔记
  • 开源项目

    • cloud-app-admin
    • 下班了吗Vscode插件
    • Subversion变更单插件
  • Server

    • Django
  • 学习笔记

    • MySQL学习笔记
  • 运维

    • 服务器部署
    • Linux
  • 日常学习

    • 学习方法
关于
收藏
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

干巴爹兔

卑微的前端打工人
首页
  • 前端文章

    • JavaScript
    • HTML
    • Vue
  • 学习笔记

    • JavaScript教程
    • React学习笔记
    • Electron学习笔记
  • 开源项目

    • cloud-app-admin
    • 下班了吗Vscode插件
    • Subversion变更单插件
  • Server

    • Django
  • 学习笔记

    • MySQL学习笔记
  • 运维

    • 服务器部署
    • Linux
  • 日常学习

    • 学习方法
关于
收藏
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • React学习

    • React入门笔记(一)
    • React入门笔记(二):JSX样式、组件初识
    • React入门笔记(三):React状态、事件绑定
    • React入门笔记(四):React生命周期、插槽、路由
      • React入门笔记(五):Redux、react-redux
    • Redux学习

    • 《React学习笔记》
    • React学习
    干巴爹兔
    2020-06-22
    目录
    五、React生命周期
    5.1、钩子函数
    六、React插槽
    6.1、插槽介绍
    6.2、使用props.children实现插槽
    七、React路由
    7.1、路由介绍
    7.2、路由三大组件
    7.3、动态路由实现
    7.4、重定向组件
    7.5、Switch组件
    7.6、使用js跳转页面

    React入门笔记(四):React生命周期、插槽、路由

    # 五、React生命周期

    # 5.1、钩子函数

    生命周期即是组件从实例化到渲染到最终从页面销毁,整个过程就是生命周期,在这个生命周期中,我们有许多可以调用的事件,我们也俗称为钩子函数

    生命周期的三个状态:

    1. Mounting:将组件插入到dom中
    2. 将数据更新到dom中
    3. unmounting:将组件移除dom

    生命周期中的钩子函数(方法或事件)

    1. ComponentWillMount:组件将要渲染,Ajax,添加动画前的类
    2. ComponentDidMount:组件渲染完毕,添加动画
    3. ComponentWillReceiveProps:组件将要接收props数据,查看接收的props数据是什么
    4. ShouldComponentUpdate:组件接收到新的state或者props,判断是否要更新,返回布尔值
    5. ComponentWillUpdate:组件将要更新
    6. ComponentDidUpdate:组件已经更新
    7. ComponentWillUnmount:组件将要卸载
    import React, { Component } from "react";
    import ReactDOM from "react-dom";
    
    class ComLife extends Component {
      constructor(props) {
        super(props);
        this.state = {
          msg: "你好",
        };
        console.log("constructor构造函数");
      }
    
      componentWillMount() {
        console.log("componentWillMount组件将要渲染");
      }
    
      componentDidMount() {
        console.log("componentDidMount组件渲染完毕");
      }
    
      componentWillReceiveProps() {
        console.log("componentWillReceiveProps组件将要接受新的状态state和props");
      }
    
      shouldComponentUpdate() {
        //如果希望更新就返回为真,不希望更新就返回为false
        console.log("进行判断是否要更新");
        if (this.state.msg === "你好") {
          return true;
        } else {
          return false;
        }
      }
    
      componentWillUpdate() {
        console.log("componentWillUpdate组件将要更新");
      }
    
      componentDidUpdate() {
        console.log("componentDidUpdate组件更新完毕");
      }
    
      componentWillUnmount() {
        console.log("componentWillUnmount组件将要移除");
      }
    
      changeMsg = () => {
        this.setState({
          msg: "你好,陈",
        });
      };
    
      render() {
        console.log("render渲染函数");
        return (
          <div>
            <h1>{this.state.msg}</h1>
            <button onClick={this.changeMsg}>组件更新</button>
          </div>
        );
      }
    }
    
    class ParentCom extends Component {
      constructor(props) {
        super(props);
        this.state = {
          isShow: true,
        };
      }
    
      removeCom = () => {
        this.setState({
          isShow: false,
        });
      };
    
      render() {
        if (this.state.isShow) {
          return (
            <div>
              <button onClick={this.removeCom}>移除ComLife</button>
              <ComLife />
            </div>
          );
        } else {
          return <h1>将ComLif移除</h1>;
        }
      }
    }
    
    ReactDOM.render(<ParentCom />, document.getElementById("root"));
    
    
    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
    90
    91
    92
    93

    image-20200621201157072

    image-20200621201208463

    # 六、React插槽

    # 6.1、插槽介绍

    在组件中写入内容,这些内容可以被识别和控制。react需要自己开发支持插槽功能。

    # 6.2、使用props.children实现插槽

    原理:组件中写入的HTML可以传入到props中

    import React, { Component } from "react";
    import ReactDOM from "react-dom";
    
    class ParentCom extends Component {
      constructor(props) {
        super(props);
      }
    
      render() {
        return (
          <div>
            <h1>组件插槽</h1>
            {this.props.children}
          </div>
        );
      }
    }
    
    ReactDOM.render(
      <ParentCom>
        <h2>子组件1</h2>
        <h2>子组件2</h2>
        <h2>子组件3</h2>
      </ParentCom>,
      document.getElementById("root")
    );
    
    
    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

    image-20200622191143265

    插槽也可以获取元素的值:

    import React, { Component } from "react";
    import ReactDOM from "react-dom";
    
    class ParentCom extends Component {
      render() {
        console.log(this.props);
        return (
          <div>
            <h1>组件插槽</h1>
            {this.props.children}
          </div>
        );
      }
    }
    
    class RootCom extends Component {
      constructor(props) {
        super(props);
        this.state = {
          arr: [1, 2, 3],
        };
      }
      render() {
        return (
          <ParentCom>
            <h2 data-name="a" data-index={this.state.arr[0]}>
              子组件1
            </h2>
            <h2 data-name="b" data-index={this.state.arr[1]}>
              子组件2
            </h2>
            <h2 data-name="c" data-index={this.state.arr[2]}>
              子组件3
            </h2>
          </ParentCom>
        );
      }
    }
    
    ReactDOM.render(<RootCom></RootCom>, document.getElementById("root"));
    
    
    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

    image-20200622191829249

    在做一个小例子,通过获取插槽内元素的值来动态的判断div放置的位置:

    import React, { Component } from "react";
    import ReactDOM from "react-dom";
    
    class ParentCom extends Component {
      render() {
        console.log(this.props);
        return (
          <div>
            <h1>组件插槽</h1>
            {this.props.children}
            <ChildCom>
              <h1 data-position="header">这是放置到头部的内容</h1>
              <h1 data-position="main">这是主要的内容</h1>
              <h1 data-position="footer">这是放置到尾部的内容</h1>
            </ChildCom>
          </div>
        );
      }
    }
    
    class ChildCom extends Component{
      render(){
        let headerCom,mainCom,footerCom
        this.props.children.forEach((item,index)=>{
          if(item.props['data-position']==='header'){
            headerCom = item
          }else if(item.props['data-position']==='main'){
            mainCom = item
          }else{
            footerCom = item
          }
        })
        return(
          <div>
            <div className="header">
              {headerCom}
            </div>
            <div className="main">
              {mainCom}
            </div>
            <div className="footer">
              {footerCom}
            </div>
          </div>
        )
      }
    }
    
    class RootCom extends Component {
      constructor(props) {
        super(props);
        this.state = {
          arr: [1, 2, 3],
        };
      }
      render() {
        return (
          <ParentCom>
            <h2 data-name="a" data-index={this.state.arr[0]}>
              子组件1
            </h2>
            <h2 data-name="b" data-index={this.state.arr[1]}>
              子组件2
            </h2>
            <h2 data-name="c" data-index={this.state.arr[2]}>
              子组件3
            </h2>
          </ParentCom>
        );
      }
    }
    
    ReactDOM.render(<RootCom></RootCom>, document.getElementById("root"));
    
    
    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

    image-20200622192707337

    组件中的HTML直接可全部插入,也可以通过条件判断来决定插入的位置

    # 七、React路由

    # 7.1、路由介绍

    根据不同的路径,显示不同的组件(内容):React使用的库:react-router-dom:

    安装:

    yarn add react-router-dom  或 npm install --save add react-router-dom
    
    1

    # 7.2、路由三大组件

    • Router:所有路由组件的根组件(底层组件),包裹路由规则的最外层容器
    • Route:路由规则匹配组件,显示当前规则对应的组件
    • Link:路由跳转的组件

    注意:如果要精确匹配,那么可以在Route上设置exact属性

    使用history模式制作一个建议的导航:

    import React, { Component } from 'react';
    // hash模式
    // import {HashRouter as Router,Link,Route} from 'react-router-dom'
    
    // history模式 后端配合使用
    import {BrowserRouter as Router,Link,Route} from 'react-router-dom'
    
    
    function Home(){
      return(
        <div>
          <h1>首页</h1>
        </div>
      )
    }
    
    function Me(){
      return(
        <div>
          <h1>个人中心</h1>
        </div>
      )
    }
    
    function Product(){
      return(
        <div>
          <h1>产品页面</h1>
        </div>
      )
    }
    
    class App extends Component{
      render(){
        return(
          <div id="app">
            <Router  basename="/admin">
              <div className="nav">
                <Link to="/">Home</Link>
                <Link to="/product">Product</Link>
                <Link to="/me">个人中心</Link>
              </div>
              <Route path="/" exact component={Home}></Route>
              <Route path="/product" component={Product}></Route>
              <Route path="/me" component={Me}></Route>
            </Router>
          </div>
        )
      }
    }
    
    export default App;
    
    
    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

    image-20200622194804418

    可以通过设置basename来规定根路径,也可以使用exact来达到精确匹配,Router可以在一个组件写多个

    import React, { Component } from "react";
    // hash模式
    // import {HashRouter as Router,Link,Route} from 'react-router-dom'
    
    // history模式 后端配合使用
    import { BrowserRouter as Router, Link, Route } from "react-router-dom";
    
    function Home() {
      return (
        <div>
          <h1>admin首页</h1>
        </div>
      );
    }
    
    function Me() {
      return (
        <div>
          <h1>admin个人中心</h1>
        </div>
      );
    }
    
    function Product() {
      return (
        <div>
          <h1>admin产品页面</h1>
        </div>
      );
    }
    
    class App extends Component {
      render() {
        return (
          <div id="app">
            <div>所有页面普通内容</div>
            <Router>
              <Route path="/" exact component={() => <div>首页</div>}></Route>
              <Route path="/me" component={() => <div>个人中心</div>}></Route>
              <Route path="/product" component={() => <div>产品</div>}></Route>
            </Router>
            <Router>
              {/* <div className="nav">
                <Link to="/">Home</Link>
                <Link to="/product">Product</Link>
                <Link to="/me">个人中心</Link>
              </div> */}
              <Route path="/admin/" exact component={Home}></Route>
              <Route path="/admin/product" component={Product}></Route>
              <Route path="/admin/me" exact component={Me}></Route>
            </Router>
          </div>
        );
      }
    }
    
    export default App;
    
    
    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

    Link组件中的to可以直接写路径,也可以通过对象,进行更详细的配置

    render() {
        let meObj = {
          pathname: "/me",//跳转的路径
          search: "?username=admin",//get请求的参数
          hash: "#abc",//设置的hash值
          state: { msg: "hello" },//传入组件的数据
        };
        return (
          <div id="app">
            <div>所有页面普通内容</div>
            <Router>
              <Route path="/" exact component={() => <div>首页</div>}></Route>
              <Route path="/me" component={() => <div>个人中心</div>}></Route>
              <Route path="/product" component={() => <div>产品</div>}></Route>
            </Router>
            <Router>
              <div className="nav">
                <Link to="/">Home</Link>
                <Link to="/product">Product</Link>
                <Link to={meObj}>个人中心</Link>
              </div>
              <Route path="/admin/" exact component={Home}></Route>
              <Route path="/admin/product" component={Product}></Route>
              <Route path="/admin/me" exact component={Me}></Route>
            </Router>
          </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

    Link的replace属性,点击链接后,将新地址替换成历史访问记录的原地址

    <Link to={meObj} replace>个人中心</Link>
    
    
    1
    2

    # 7.3、动态路由实现

    function News(props){
      console.log(props)
      return(
        <div>
          新闻页
          新闻id:{props.match.params.id}
        </div>
    
      )
    }
    
    ...
    
    <Router>
              <div className="nav">
                <Link to="/">Home</Link>
                <Link to="/product">Product</Link>
                <Link to="/news/456789">新闻页面</Link>
                <Link to={meObj} replace>个人中心</Link>
              </div>
              <Route path="/admin/" exact component={Home}></Route>
              <Route path="/admin/product" component={Product}></Route>
              <Route path="/admin/me" exact component={Me}></Route>
              <Route path="/news/:id" component={News}></Route>
            </Router>
    
    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

    image-20200622202336013

    # 7.4、重定向组件

    如果访问访问某个组件时,如果有重定向组件,那么就会修改页面路径,使得页面的内容显示为所定向路径的内容:

    import React, { Component } from "react";
    // hash模式
    // import {HashRouter as Router,Link,Route} from 'react-router-dom'
    
    // history模式 后端配合使用
    import {
      BrowserRouter as Router,
      Link,
      Route,
      Redirect,
    } from "react-router-dom";
    
    function LoginInfo(props) {
      // props.LoginState = 'success'
      // props.LoginState = 'fail'
      if (props.location.state.loginState === "success") {
        return <Redirect to="/admin"></Redirect>;
      } else {
        return <Redirect to="/login"></Redirect>;
      }
    }
    
    let FormCom = () => {
      let pathObj = {
        pathname:"/login_info",
        state:{
          loginState:"success"
        }
      }
      return (
        <div>
          <h1>表单验证</h1>
          <Link to={pathObj}>登陆验证后页面</Link>
        </div>
      );
    };
    
    class App extends Component {
      render() {
        return (
          <div>
            <Router>
              <Route path="/" exact component={() => <h1>首页</h1>}></Route>
              <Route path="/form" exact component={FormCom}></Route>
              <Route path="/login" exact component={() => <h1>登陆页</h1>}></Route>
              <Route path="/login_info" exact component={LoginInfo}></Route>
              <Route path="/admin" exact component={() => <h1>admin页,登录成功</h1>}></Route>
            </Router>
          </div>
        );
      }
    }
    
    export default App;
    
    
    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

    # 7.5、Switch组件

    让Switch组件内容的route只匹配一个,只要匹配到了,剩余的路由规则将不被匹配

    render() {
        return (
          <div>
            <Router>
              <Switch>
                <Route path="/" exact component={() => <h1>首页</h1>}></Route>
                <Route path="/form" exact component={FormCom}></Route>
                <Route path="/login" exact component={() => <h1>登陆页</h1>}></Route>
                <Route path="/login_info" exact component={LoginInfo}></Route>
                <Route path="/admin" exact component={() => <h1>admin页,登录成功</h1>}></Route>
                <Route path="/abc" exact component={() => <h1>abc1</h1>}></Route>
                <Route path="/abc" exact component={() => <h1>abc2</h1>}></Route>
              </Switch>
            </Router>
          </div>
        );
      }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    image-20200622210156066

    # 7.6、使用js跳转页面

    使用props的histroy中的属性和方法来进行页面路由的跳转:

    class ChildCom extends Component{
    
      clickEvent = () =>{
        //console.log(this.props)
        this.props.history.push('/',{msg:"这是由ChildCom发给首页的数据"})
        this.props.history.replace('/',{msg:"这是由ChildCom发给首页的数据"})
          //前进
        this.props.history.go(1)
        this.props.history.goForward(1)
        //后退
        this.props.history.go(-1)
        this.props.history.goBack(-1)
      }
    
      render(){
        return(
          <div>
            <button onClick={this.clickEvent}>跳转到首页</button>
          </div>
        )
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    image-20200622211116940

    props.match可以获取到动态路由传递的参数:

    <Route path="/:id" exact component={(props) => {console.log(props); return (<h1>首页</h1>)}}></Route>
    
    1

    image-20200622211538258

    编辑 (opens new window)
    #React
    上次更新: 2022/08/26, 15:52:02
    React入门笔记(三):React状态、事件绑定
    React入门笔记(五):Redux、react-redux

    ← React入门笔记(三):React状态、事件绑定 React入门笔记(五):Redux、react-redux→

    最近更新
    01
    使用Vscode开发一个小插件
    10-21
    02
    Vscode插件配置项监听
    10-18
    03
    使用has属性构造必填效果
    10-14
    更多文章>
    Theme by Vdoing | Copyright © 2020-2025 互联网ICP备案: 闽ICP备18027236号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式