• react笔记基础部分(组件生命周期路由)


    注意点:

    class是一个关键字, 类。 所以react 写class, 用classname ,会自动编译替换class

    点击方法:

     
    
    • 1

    常用的插件:

    需要引入才能使用的:

     路由五兄弟
     
    import {BrowserRouter as Router, Link, Route, Redirect, Switch} from 'react-router-dom'
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    react-redux

    npm install react-redux --save

    初始配置 app页面

    import React from 'react';
    import logo from './logo.svg';
    import './App.css';
    
    function App() {
      return (
        <div className="App">
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <p>
              Edit <code>src/App.js</code> and save to reload.
            </p>
            <a
              className="App-link"
              href="https://reactjs.org"
              target="_blank"
              rel="noopener noreferrer"
            >
              Learn React
            </a>
          </header>
        </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

    1.react简介:

    简介:React 构建用户界面的javascript库,主要用于构建按ui界面。 instagram,2013年开源。

    特点:

    • 声明式的设计
    • 高效,采用虚拟DOM来实现DOM的渲染,最大限度的减少DOM的操作
    • 灵活,跟其他库灵活搭配使用
    • jsx, 俗称给你JS 里面写HTML, JavaSxript 语法的扩展。
    • 组件化,模块化。代码容易复用,大型项目非常喜欢react.(2016年前,vue还没有火之前)
    • 单项数据流/没有实现数据的双向绑定。 数据 --> 视图 --> 事件 --> 数据

    2 使用 引入react

    2.1 CDN:

    只用于本地的学习和使用。 线上形目不能这样啊

    可以通过 CDN 获得 React 和 ReactDOM 的 UMD 版本。

    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    
    • 1
    • 2

    2.2 脚手架

    cnpm install -g create-React-app

    # 全局安装"create-react-app"架构
    $ npm install -g create-react-app
     
    # 创建脚手架项目
    $ create-react-app my-app
     
    # 进入项目目录
    $ cd my-app
     
    # 启动项目
    $ npm start
    
    http://localhost:3000/
    
    执行npm start 时, 会自动编译dom,插入到src中的index.html,因为浏览器才不管你用了什么插件,他只会显示解析html正常的dom。
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    3. npm start 发生了什么 代码原理

    入口文件:
    1.网页入口文件放在 dist/index.html
    2. react入口文件放在 src/index.js
    
    在package.json的script中新增命令
    "scripts": {
        "dev": "cross-env NODE=dev"
    }
    
    
    
    $ npm run build
    # 等同于执行
    $ node build.js
    
    npm start是npm run start  简写形式
    
    也就是说npm start=  node start.js 执行文件
    npm run 查看当前项目的所有的
    
    
    https://blog.csdn.net/cuipengchong/article/details/73044737?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159479718919724811836533%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159479718919724811836533&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v3~pc_rank_v3-1-73044737.pc_ecpm_v3_pc_rank_v3&utm_term=npm%E8%84%9A%E6%9C%AC+npm+scripts
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    npm脚本 npm scripts
    概念: npm脚本指的是package.json中的scripts字段
    npm允许在package.json文件里面,使用scripts字段定义脚本命令。
    就像 node 中执行1.js 可以写成 node 1  一样
    
    "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
      },
    
    scripts:{
    "build":'node build.js'
    }
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    ----------------------分割线--------------------------

    https://blog.csdn.net/qq_39956624/article/details/89352115?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159479854019195264540861%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=159479854019195264540861&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v3~pc_rank_v3-1-89352115.pc_ecpm_v3_pc_rank_v3&utm_term=react-scripts+start

    在命令窗口输入的是npm start,而start调用的是

     package.json 中的
     
     "start": "react-scripts start",
    
    • 1
    • 2
    • 3

    代码会找到 node_modules里面的react-scripts 插件。查找 bin 文件 点开bin\react-scripts.js文件内容

     .concat(require.resolve('../scripts/' + script))
     从上面这话可以看出调用start时需要调用scripts/start.js,点开该文件:
    
    
    • 1
    • 2
    • 3
    1. 打开config/paths.js,发现其实里面好多默认的配置都是写在该文件,可以通过修改改文件来实现自己文件的存放配置
    2. 点开webpack.config.dev.js,也会发现大量是曾相识的代码:
    3. 所以说我们以前通过手动配置的webpack.config.js的内容,react-scripts都已经帮我们做了,大大方便了我们的使用。

    ----------------------分割线--------------------------

    npm的原理

    npm 脚本的原理非常简单。每当执行npm run,就会自动新建一个 Shell,在这个 Shell 里面执行指定的脚本命令。因此,只要是 Shell(一般是 Bash)可以运行的命令,就可以写在 npm 脚本里面。

    比较特别的是,npm run新建的这个 Shell,会将当前目录的node_modules/.bin子目录加入PATH变量,执行结束后,再将PATH变量恢复原样。

    这意味着,当前目录的node_modules/.bin子目录里面的所有脚本,都可以直接用脚本名调用,而不必加上路径。比如,当前项目的依赖里面有 Mocha,只要直接写mocha test就可以了。

    例如

    “test”: “mocha test”
    1
    而不用写成下面这样。

    “test”: “./node_modules/.bin/mocha test”

    npm传参

    向 npm 脚本传入参数,要使用–标明。

    “lint”: “jshint **.js”
    1
    向上面的npm run lint命令传入参数,必须写成下面这样。

    $ npm run lint – --reporter checkstyle > checkstyle.xml

      "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test --env=jsdom",
        "eject": "react-scripts eject"
      }
    
    里面是一个个键值对,eject对应react-scripts eject,
    
    当我们执行 npm eject的命令是,npm会找到 package.json中的scripts对象中eject对相应值,然后在执行。
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    react文档结构

    myreact 
    
     
     |--node_modules   项目依赖包
     |-- public       公共开放资源  静态资源
     |     |--favicon.ico 
     |     | --index.html      相当于vue的 id ='app',等待放置编译好的dom
     |     | --logo.png         react图表
     |     | --mainifest.json  chrome扩展文件
     |     | --robots.txt       告诉爬虫,不要爬我的网页。一般没用。
     |
     |-- src
     |     |--App.css
     |     | --APP.js    app组件
     |     | --App.test.js
     |     | --index.css
     |     | --index.js   入口文件
     |     | --logo.svg
     |     | --servceWorker.js
     |     | --setupTests.js
     |
     | --.gittignore    git 忽略配置文件
     | --package.json    包配置信息
     | --package-lock.json  包配置信息版本固定
     | --README.md         文档说明   
     
     
    webpack.config.js -  node_modules 
    
    
    
    
    • 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

    关于import…form…

    index.js主文件为例

    import '../gen'  // 不支持根目录下的相对引入文件
    
    import './1.js'
    // require ('./1.js')  这两种引入方式,都可以打包进去。
    
    自己的静态图片,官方希望你都放在src中,不要访问外边的资源。img js 新建目录存放。
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4 react 组件原理

    这是一个组件

    App.js

    function App() {
      return (
          
        <div className="App">
            我是内容
        </div>
    
      );
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    这是

    index.js 引用的页面

    import App from './App';  1.引入
    
    
    ReactDOM.render(  2.  调用一个方法
      //   严格模式
        <App />,
      // ,
      document.getElementById('root')
    );
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    测试1:函数式组件渲染

    index.js

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import * as serviceWorker from './serviceWorker';
    
    // ReactDOM.render(
    //     ,
    //   document.getElementById('root')
    // );
    
    // If you want your app to work offline and load faster, you can change
    // unregister() to register() below. Note this comes with some pitfalls.
    // Learn more about service workers: https://bit.ly/CRA-PWA
    serviceWorker.unregister(); //缓存
    
    页面生成时间,1s刷线一次。
    function clock(){
      let time = new Date().toLocaleTimeString();
    let element = 
    {time}
    ; let root = document.getElementById('root'); ReactDOM.render(element,root); } setInterval(clock,1000 )
    • 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

    测试2:组件传参

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    
    function Clock(props) {
      console.log(props);  //2.props  { data1:4,data2:40 }传入的值,会放到形参中。
      return ( 
        <div > 
         {  props.data1}
          </div>
        )
      }
    
    function run(){
    
      ReactDOM.render(
      <Clock data1 = { 4} data2 = { 40}/>, //1. 标签首位字母大写
    
    document.getElementById('root')
      );
      
    }
      setInterval(run, 1000)
    
    
      // let time = new Date().toLocaleTimeString(); 
      //不同点: props
    
    
    • 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

    5 Jsx 表达式

    优点:

    • JSX执行更快,编辑为JavsScript 代码是进行优化。

    • 类型更安全,编译过程如果出错就不能编译,及时发现错误。

    • JSX编写模板更加简单快速(不要更vue比,当时VUE还没出来)

      注意点:*

      1. jsx必须要有根节点
      2. 正常的普通HTML元素要小写,如果是大写,默认认为是组件。

      jsx表达式:

      1. 有HTML元素构成
      2. 中间使用变量 用 { }
      3. {} 中可以使用表达式 可以使用 jsx对象,
      4. 属性和html内容一样都是用{} 来插入内容。
      5. {} 一个只能放一个表达式 但可以放入嵌套数据结构

    { }

    1.里放置表达式
    案例1var msg = '姓名';
    var time = '00:00'
    
    var dom = (
             <div>
                    <div> {msg + time}</div>
            </div>
     )
    
    ReactDOM.render(
      dom,
      document.getElementById('root')
     )
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    2.案例2 :三元运算法

    { } 里面可以放标签和单元判断

    var msg = '发烧';
    var dom = (
             
    {msg == '发烧'? :'没事啊'}
    ) ReactDOM.render( dom, document.getElementById('root') )
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    3. 混搭

    {插值中放入标签,三元判断等}

    var element4 = '我是混搭';
    or
    
    var element4 =
        <div>
              <span> 我是模板混搭 <sapn/> 
         </div>
    
    
    <div> {msg == '发烧'?  <button>隔离</button> :element4}</div>
       
      dom变成了什么:     
    element4:  dom,在这里已经变成了 一个对象。有属性和  _proto_       
           
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    4 引入css

    App.css

    .lyx{
      color: red;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    import引入 css 文件

    比如当前页 index.js

    直接引入
    import './App.css';
    
    注意点: 
    
    {msg == '发烧'?
    隔离
    :'没事啊'}
    加clsss 写法注意 className, 测试: 直接写 calss='lyx' 也可以。但是浏览器里会提示错误。
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    变量js方式 css
    let  styledemo = {
      background:"skyblue",
      borderBottom:"4px solid red",  //需要驼峰
        "fontsize":'40px'    //要么加引号,不用驼峰
    }
    
    let element = (
    <div>
      <h1 style = { styledemo} >我是 react style 的jsx变量写法</h1>
    </div>
    )
    
    
    ReactDOM.render(
      element,
      document.getElementById('root')
     )
    
    * 不能写行内样式,报错
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    添加 自定义 class

    let classstr = 'redbg'
    
    let element = (
    <div>
      <h1 style = { styledemo} className = {'abc '+ classstr}>我是 react style 的jsx变量写法</h1>
    </div>
    )
    
    变量类名 和自定义类名, abc 字符串类型,记得一定留出空格。否则编译出来会合并
    className = {'abc '+ classstr} 
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. 同时添加多个class

    jsx标签中,不能加多个class, 需要处理一下,把class合并在写入。

    let classstr = ["redbg","redbg2"].join(" ") //合并字符串当成一个变量放入插值中
    
    let element = (
    <div>
      <h1 style = { styledemo} className = {classstr}>我是 react style 的jsx变量写法</h1>
    </div>
    )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5. jsx中加注释

    let element = (
    <div>
      {/* jsx的注释写法*/}
      <h1 style = { styledemo} className = {classstr}>我是 react style </h1>
    </div>
    )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    6. 组件的两种方式

    6.1编程式 函数里(静态组件)

    function Childdom(){
      let title = <h2> 我是副标题</h2>
      let weather = '下雨'
    //条件判断
     let isgo = weather === '下雨' ? "下雨不出门" : "不下雨了,不出门" 
      return(
      <div>  
        {title} 
        <span>
          天气怎么样:
          {isgo}
        </span>
        
      </div>
      )}
    
    ReactDOM.render(
      <Childdom/>,
      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

    另一种传值形式,也是编程式 (组件传值)

    function Childdom(props){
      let title = <h2> 我是副标题</h2>
    console.log(props);  // props接受传值
      return(
      <div>  
            {title} 
                <span>
                  天气怎么样:
                      {props.weather}    // 使用传值
                </span>
        
      </div>
      )}
       
    ReactDOM.render(
      <Childdom weather = '来自组件标签'/>,   //标签传值
    
      document.getElementById('root')
     )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    6.2 类组件 class声明(动态组件)

    index.js

    class HelloWorld extends React.Component{
     render() {                //render这个名字不能动。不是随意取得。是一个规定的方法
          return(
            <div>  
            我是类组件定义
            </div>
          )
     }
    }
    
    
    ReactDOM.render(
      <HelloWorld/>,
      document.getElementById('root')
     )
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    组件

    类组件传参-见序号8

      class Ant extends React.Component {
        constructor(props) {
          super(props)
        this.state = {}
        }
      
        render() {
    
          return ( 
            <div > 
              
            </div>
          )
        }
    
        onChange(page,pagesize){
         
        }
      }
    
    
    export default Ant
    
    
    
    
    • 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

    6.3组件嵌套(复合组件)

    class Children extends React.Component{
      render() {               
           return(
             <div>  
         <div> 我是Children</div>
    
    
             </div>
           )
      }
     }
    
      class HelloWorld extends React.Component{
        render() {              
             return(
               <div>  
           <div> 我是HelloWorld</div>
              <Children/>    //helloworld组件中,引入children组件
               </div>
             )
        }
       }
       
       ReactDOM.render(
         <HelloWorld  weather = '出太阳'/>,
         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

    结论:两种组件适用场景

    函数式: 如果静态,或者就 传一个值,使用函数式

    类组件:有触发事件,交互和操作

    7. 关键方法:ReactDOM.rende

    ReactDOM.render(组件, 挂载点root)
    
    
    
    • 1
    • 2
    • 3

    组件这一块,样式可以多种。

    第一种 : function ( ) 函数形式

    function Childdom(){
      let title = <h2> 我是副标题</h2>
      let weather = '下雨'
    //条件判断
     let isgo = weather === '下雨' ? "下雨不出门" : "不下雨了,不出门" 
      return(
      <div>  
        {title} 
        <span>
          天气怎么样:
          {isgo}
        </span>
        
      </div>
      )}
    
    ReactDOM.render(
      <Childdom/>,
      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

    第二种 : dom形式

    其实实质一样,和return() 函数式一样。
    
    let element = (
    <div>
      <h1 style = { styledemo} >我是 react style 的jsx变量写法</h1>
    </div>
    )
    
    
    ReactDOM.render(
      element,
      document.getElementById('root')
     )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    8 传值

    function Childdom(props){
      let title = <h2> 我是副标题</h2>
    console.log(props);  // props接受传值
      return(
      <div>  
            {title} 
                <span>
                  天气怎么样:
                      {props.weather}    // 使用传值
                </span>
        
      </div>
      )}
       
    ReactDOM.render(
      <Childdom weather = '来自组件标签'/>,   //标签传值
    
      document.getElementById('root')
     )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    8 传值(类组件传参)

    8.1 自己的标签 ——> 传向自己的组件

    class Children extends React.Component{
      render() {     
        console.log(this);   //这里的this指的是Children组件 this里propos里有标签传值
           return(
             <div>  
         <div> 我是Children</div>
    
    
             </div>
           )
      }
     }
    
      class HelloWorld extends React.Component{
        render() {       
          console.log(this);   //这里的this指的是HelloWorld组件 this里propos里有标签传值
             return(
               <div>  
           <div> 我是HelloWorld</div>
              <Children name = '我是children的数据' />   
               </div>
             )
        }
       }
       
       ReactDOM.render(
         <HelloWorld  weather = '我是父组件穿的值'/>,
         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

    8.2 父组件 标签的数据–> 子组件 传递

    class Children extends React.Component{
      render() {     
        // console.log(this);   //这里的this指的是Children组件 this里propos里有标签传值
           return(
             <div>  
         <div> 我是Children</div>
    
    
             </div>
           )
      }
     }
    
      class HelloWorld extends React.Component{
        render() {       
          console.log(this);   //这里的this指的是HelloWorld组件 this里propos里有标签传值
             return(
               <div>  
           <div> 我是HelloWorld</div>
              <Children name = '我是children的数据' weather = {this.props.weather}/>   
               </div>
             )
        }
       }
       
       ReactDOM.render(
         <HelloWorld  weather = '我是父组件穿的值'/>,
         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

    9 react状态 管理(修改数据)

    9.1 引入例子

    class Clock extends React.Component {
      constructor(props) {
        super(props)
      this.state = {
        time: new Date().toLocaleTimeString()
        }}
    
      render() {
     // console.log(1);  变了
        return ( 
          <div >
        <h1> 当前时间: {this.state.time}</h1>
          </div>
        )
      }
    }
    
    setInterval(()=>{
      // console.log(0);  变了
    ReactDOM.render(
      <Clock/> ,
      document.getElementById('root')
    );
    
    },1000)
    
    计时器1s渲染一次,我们发现页面没动。手动刷新才会变。
    通过打印我们发现,render, 计时器都在变,就是页面不变。
    原因是: render方法 每隔1s渲染, <Clock/> 直接加载缓存。所以没变。
    
    
    • 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

    既然render变了,那就直接修改state.time的值。

     做如下修改
    render() {
      // console.log(0);
                  this.state.time = new Date().toLocaleTimeString()
        return ( 
          <div >
                     <h1> 当前时间: {this.state.time}</h1>
          </div>
        )
      }
      
      保存后,页面动了。 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    但是这不是官方推荐的方法。

    9.2 正确修改方法 setState( )

    class Clock extends React.Component {
        平级1
      constructor(props) {
        super(props)
          this.state = {
        time: new Date().toLocaleTimeString()
        }}
      平级2
      render() {
        return ( 
          <div >
                     <h1> 当前时间: {this.state.time}</h1>
          </div>
        )
      }
        平级3
       componentDidMount(){   componentDidMount是声明周期函数,加载完页面开始执行。
        setInterval(() => {
          
          this.setState({
            time : new Date().toLocaleTimeString()
          })
        }, 1000);
       }
    }
    
    渲染函数
    ReactDOM.render(
      <Clock/> ,
      document.getElementById('root')
    );
    
    
    1.采用官方方法的作用: 修改数据,并自动渲染页面;
    2. setstate方法,修改数据后,不会立即更改dom,而是等函数执行完了以后,统一对比虚拟dom,再做修改,提升性能。 小程序也是借鉴这样。
    
    
    • 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

    总结: react 类组件中,自己的state数据,和点击事件,和渲染dom,都放到自己的内部,this下挂载。

    9.3 案例:

    实现两个按钮接环内容
    import React from 'react';
    import ReactDOM from 'react-dom';
    
    class Clock extends React.Component {
      constructor(props) {
        super(props)
      this.state = {
        c1:"content active",
        c2:"content "
    
        }
        this.clickEvent = this.clickEvent.bind(this)// 把方法挂载到this组件下
    
      }
    
          clickEvent(e){
            console.log(this);
              // console.log(e.target.dataset);
              // console.log(e.target.dataset.index);
    
             let index = e.target.dataset.index
             if(index == '1'){
               this.setState({
                c1:"content active",
                c2:"content "
               })
             }else{
              this.setState({
                c1:"content ",
                c2:"content  active"
               })
             }
          }
    
      render() {
        return ( 
          <div >
                 <button data-index = '1' onClick = {this. clickEvent }>内容一</button>  
                 <button data-index = '2' onClick = {this. clickEvent }>内容二</button>  
                
                 <div className = {this.state.c1}>
                              <h1>内容一</h1>   
                 </div>
                 <div className = {this.state.c2}>
                              <h1>内容二</h1>   
                 </div>
    
          </div>
        )
      }
      
    }
    
    ReactDOM.render(
      <Clock/> ,
      document.getElementById('root')
    );
    
    案例里:用到了几个点
    e 事件对象
    DOM data自定义属性和使用
    bing(this) 改变this指向
    
    
    
    • 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

    10 传值

    10.1 父传子

    父传子数据,单向流动,不能子传父。 props的传值,可以是任意的类型。

    props可以设置默认值。

    HelloMessage.dafaultProps = { name:‘tom’ ,msg:‘hellowlorld’ }

    注意:prop可以传递函数,可以传递父元素的函数。也就是说,可以修改父元素的state数据,从而道道传递 数据 的效果和目的。

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    class Clock extends React.Component {
      constructor(props) {
        super(props)
      this.state = {
        isshow:true
    
        }
          this.changeshow = this.changeshow.bind(this)
      }
    
      changeshow(){
        this.setState({
          isshow:!this.state.isshow
        })
        
             }
    
    
      render() {
        return ( 
          <div >
            <button onClick = {this.changeshow}>控制子元素显示</button>
                <Children  isactive = {this.state.isshow}/>
    
          </div>
        )
      }
      
    }
    
    class Children extends React.Component {
      constructor(props) {
        super(props)
      this.state = {
        }
    
      }
    
          render() {
            let strclass = null;
    
            if(this.props.isactive){
              
              strclass = 'active'
            }else{
          
              strclass = ""
            }
    
        return ( 
          <div >
            <span className = {'content '+ strclass}>i is children</span>
          </div>
        )
      }
      
    }
    
    ReactDOM.render(
      <Clock/> ,
      document.getElementById('root')
    );
    
    总结: 父元素states准备一个变量,在自己函数内,子组件标签,输入值, 子组件接受props接受使用。
    
    
    • 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

    10 2 子传父

    方法: 调用父元素的函数,从而操作元素的数据。

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    
    
    
    class Clock extends React.Component {
      constructor(props) {
        super(props)
       this.state = {
        childData:null  //默认是null页面不会显示,只有 有数据才会显示
       }
        
      }
    
    
      render() {
        return ( 
          <div >
          <h1>子元素传递给复原的数据 {this.state.childData} </h1>
          <Children setChildDate = {this.setChildDate} />       //1. 变量也可以是个方法
    
          </div>
        )
      }
      setChildDate = (a)=>{  //3.传递形参,进行修改
        this.setState({
          childData:a
        })
      }
    }
    
    class Children extends React.Component {
      constructor(props) {
        super(props)
      this.state = {
        msg:'helloworld'
        }
      }
    
      sendData = ()=>{
          this.props.setChildDate(this.state.msg) // 2. 你要记住,标签传参,实例中props中就会有值。
      }
          render() {
            return ( 
              <div >
                <button onClick = {this.sendData}>给父元素传值</button>
              </div>
            )
      }
    }
      ReactDOM.render(
        <Clock/> ,
        document.getElementById('root')
      );
    
    简写形式: 既然children标签传入, children的props中就会挂载。那么就可以这样写:
     <button onClick = {()=> {this.props.setChildDate('我是子组件调用props')}}>给父元素传值</button> ,这样也是可以调用的。   匿名的箭头函数,this.不变。
    
    
    
    • 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

    11 reach 事件语法

    特点:
    1. 事件的 click 写法,驼峰命名法。2. { } 传入一个函数,而不是一个字符串.
    <button onClick = {this.sendData}>给父元素传值</button>
    
    
    • 1
    • 2
    处理过的事件对象e 和 阻止默认
    import React from 'react';
    import ReactDOM from 'react-dom';
    
    
    class Clock extends React.Component {
      constructor(props) {
        super(props)
       this.state = {
     
       }
      }
      render() {
        return ( 
          <div >
       <div onClick = { this.parentEvent } data-index = 'lyx'>
         查看事件对象e
       </div>
          </div>
        )
      }
      parentEvent = (e)=>{
        console.log( e) //注意:这个事件都想是react 处理过的。如果想拿到具体值,直接输出 e.target.dataset.index
      }
    }
      ReactDOM.render(
        <Clock/> ,
        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

    阻止默认

      组件: 
    form 有默认提交事件,同步的。如果想自定义ajax异步请求,就阻止默认。
    render() {
        return ( 
          <div >
                 <form action="https://www.baidu.com" method="get">
                         <button onClick = {this.parentEvent}>提交</button>
               </form>
          </div>
        )
      }
      
      
      方法1parentEvent = (e)=>{
        console.log(e ) //注意:想知道e中有什么方法,打印出来一个一个查一下。 
        e.preventDefault()
      }
      方法2
      form中的提交按钮,submit修改为button , 不设置默认submit.
      <button onClick = {this.parentEvent} type = 'submit'>提交</button>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    传参,同时保留事件对象
      render() {
        return ( 
          <div >
               <form action="https://www.baidu.com" method="get">
              <button onClick = {(e)=>{this.parentEvent(e, "0")}} type = 'button'>提交</button>
               </form>
          </div>
        )
      }
      parentEvent = (e,a)=>{
        console.log(e ,a) //注意:想知道e中有什么方法,打印出来一个一个查一下。 
        // e.preventDefault()
      }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    注意:
    <button onClick = {()=>{this.parentEvent("0")}} type = 'button'>提交
    
    这样的话,传值,会把e替换。
    
    
    • 1
    • 2
    • 3
    • 4
    不适用箭头函数传递多个参数

    箭头函数与function函数的区别,就是this. 所以bind,修改一下this.指向。

    function, 内部的this,就是它自己,谁调用,指向谁。

    使用箭头函数
    <button onClick = {()=>{this.parentEvent("0")}} type = 'button'>提交</button>
    不适用箭头函数
     <button onClick = {function(e){this.parentEvent('msg:helloworld',e)}.bind(this)} type = 'button'>提交</button>
    
    
     parentEvent = (e,a)=>{
        console.log(e ,a)  //形参,按位置传递 
      
      }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    12 条件渲染

    React 中条件渲染即和JavaScript 中,条件运算,如if else 三元运算符等等。

    1 直接通过条件渲染你返回要渲染的jsx对象。

    2 通过条件运算得出jsx对象,在将jsx对象渲染到模板中。

    第一种
    import React from 'react';
    import ReactDOM from 'react-dom';
    
    function User(props){
      return ( <h1>我登陆了</h1>)
    }
    
    function UserNologin(props){
      return ( <h1>请登录</h1>)
    }
    
    class Clock extends React.Component {
      constructor(props) {
        super(props)
       this.state = {
          islogin:false
       }
      }
      render() {
        if(this.state.islogin){
          return(<User></User>)
        }else{
          return(<UserNologin></UserNologin>)
        }
      }
    }
    
      ReactDOM.render(
        <Clock/> ,
        document.getElementById('root')
      );
    通过控制islogin, 达到页面变化。
    
    
    
    • 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
    第二种
    import React from 'react';
    import ReactDOM from 'react-dom';
    
    
    
    function User(props){
      return ( <h1>我登陆了</h1>)
    }
    
    function UserNologin(props){
      return ( <h1>请登录</h1>)
    }
    
    class Clock extends React.Component {
      constructor(props) {
        super(props)
       this.state = {
          islogin:false
       }
      }
      render() {
        let element = null
    
        if(this.state.islogin){
          element =( <User></User> )
        }else{
          element =  (<UserNologin></UserNologin>)
        }
    
          return(  
            <div> 
              <div>这是头部</div>
                {element}
            <div>这是尾部</div>
            </div>
          )
      }
    }
    
    
    
      ReactDOM.render(
        <Clock/> ,
        document.getElementById('root')
      );
    
    //可以发现, react 就是你想要什么样的逻辑,自己动手。
    
    
    • 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
    第三种: 三元运算符形式
    render() {
       
          return(  
            <div> 
              <div>这是头部</div>
                {this.state.islogin ?( <User></User> ):  (<UserNologin></UserNologin>)}
            <div>这是尾部</div>
            </div>
          )
      }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    13 列表渲染

    将列表内容拼装成数组放置到模板中。

    将数据封装成数组的JSX对象。

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    
    
    let arr = ['小明','小黑','小白']
    
    class Clock extends React.Component {
      constructor(props) {
        super(props)
       this.state = {
          islogin:true
       }
      }
              render() {
                  return(  
                    <div> 
                        <ul>
                              {arr}
                        </ul>
                    </div>
                  )
              }
    }
    
      ReactDOM.render(
        <Clock/> ,
        document.getElementById('root')
      );
    
    
    渲染结果:
    <ul>
      小明
    小黑
    小白
    </ul>
    
    
    • 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

    改造:

    let arr = ['小明','小黑','小白']
    
    我们设置一个jsx数组
    
    let arrhtml = [<li>小明</li>,<li>小黑</li>,<li>小白</li>]
    
                   
      render() {
                  return(  
                    <div> 
                        <ul>
                              {arrhtml}
                        </ul>
                    </div>
                  )
              }
            
    渲染结果: 完美
    <ul><li>小明</li><li>小黑</li><li>小白</li></ul>
          
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    列表循环jsx。

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    
    class Clock extends React.Component {
      constructor(props) {
        super(props)
       this.state = {
         listarr : [
           {
              title:'第一个标题1',
              cont:'我是内容1'
           },
           {
              title:'第一个标题2',
              cont:'我是内容2'
           }
         ]
       }
      }
              render() {
                let listArr = []
                console.log(0);
                for(let i = 0 ;i < this.state.listarr.length;i++){
          
                  var  item =  (
                    <li>
                      <h3>{this.state.listarr[i].title}</h3>
                       <p>{this.state.listarr[i].cont}</p>
                    </li>
                  )
                  listArr.push(item) 
                }
          
                  return(  
                    <div> 
                        <ul>
                              {listArr}
                        </ul>
                    </div>
                  )
              }
    }
    
    
    
      ReactDOM.render(
        <Clock/> ,
        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

    代码简化 map循环

    使用数组的map方法,对每一项数据按照JSX的形式加工,最终得到,每一项都是JSX对象的数组,在将数组渲染到模板中去。

      render() {
                let listArr = this.state.listarr.map((itme,index)=>{
                  return(
                 <div key = {index} className = {'item'+index}>
                        <li>{itme.title}</li>
                        <p>{itme.cont}</p>
                 </div>
                
                  )
                })
                  return(  
                    <div> 
                        <ul>
                              {listArr}
                        </ul>
                    </div>
                  )
              }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    14 肺炎列表渲染案例

    总结: render里面可以写js逻辑,完全就是原生js写的。

    这个暂用:

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    var data = require('./1.json')
    console.log(data);
    
    class Clock extends React.Component {
      constructor(props) {
        super(props)
       this.state = {
         listarr : [
           {
              title:'第一个标题1',
              cont:'我是内容1'
           },
           {
              title:'第一个标题2',
              cont:'我是内容2'
           }
         ]
       }
      }
              render() {
                let listArr = this.state.listarr.map((itme,index)=>{
                  return(
                 
  • {itme.title}
  • {itme.cont}

    ) }) return(
      {listArr}
    ) } } ReactDOM.render( , 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

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    15 生命周期函数

    https://blog.csdn.net/qq_38719039/article/details/82378434

    img

    生命周期: 针对组件总渲染到销毁的过程。期间有可以调用的函数,又叫钩子函数

    生命周期的3个状态。

    Mounting: 将组件插入到dom中。

    Updating: 将数据更新到dom中。

    Unmounting: 将组件移除Dom中。

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

    componentWillMount: 组件将要渲染 -> AJAX,添加动画前的类

    componentDidMount : 组件渲染完毕 -> 添加动画 添加echart 就在这里 获取windown

    compontWillReceiveProps:组件将要接受props数据 ->查看props的数据是什么

    componentWillReceiveProps: 组件接收到新的state或者props ->判断是否更新。 返回布尔值。

    CompontWillUpdate : 组件将要更新

    componentDidUpdate :组件已经更新

    componentWillUnmount : 组件 将要卸载

    // 已经更正

    1.constructor(props, context)

    • 构造函数,在创建组件的时候调用一次。

    2.componentWillMount()

    • 在组件render之前立即调用

    Tip1: 不建议在此请求数据,由于请求数据接口一般都是异步,这时候render已经被执行,建议在componentDidMount 数据

    Tip2: 如果在服务端渲染,该钩子函数将被调用两次,一次服务端,一次浏览器端,而componentDidMount函数只会在浏览器端请求一次

    Tip3: 在taro构建的小程序里对应的生命周期是 onLoad。

    3…componentDidMount()

    • 所有的组件(包括子组件)在render执行完之后立即调用,并且只会被调用一次。

    Tip: 建议在此请求数据

    4. componentWillReceiveProps(nextProps)

    • 在props被改变时被触发,初始化render时不调用。
    • 旧的属性还是可以通过this.props来获取,在这里通过调用this.setState()来更新你的组件状态。

    Tip1: 某些情况下,props没变也会触发该钩子函数,需要在方法里手动判断一下this.props和nextProps是否相同,不相同了才执行我的更新方法。

    Tip2:该函数一般用来更新依赖props的状态

    5. shouldComponentUpdate(nextProps, nextState)

    • 发生重渲染时,在render()函数调用前被调用的函数,当函数返回false时候,阻止接下来的render()函数的调用,阻止组件重渲染,而返回true时,组件照常重渲染。
    • 该方法并不会在初始化渲染或当使用forceUpdate()时被调用。

    6.componentWillUpdate(nextProps, nextState)

    • shouldComponentUpdate返回true或者调用forceUpdate之后,componentWillUpdate会被调用。

    7. getSnapshotBeforeUpdate(prevProps, prevState)

    • 该函数在最新的渲染输出提交给DOM前将会立即调用。它让你的组件能在当前的值可能要改变前获得它们。这一生命周期返回的任何值将会 作为参数被传递给componentDidUpdate()。

    8. componentDidUpdate(prevProps, prevState)

    • 除了首次render之后调用componentDidMount,其它render结束之后都是调用componentDidUpdate。

    9.componentWillUnmount()

    • 在组件被卸载和销毁之前立刻调用。可以在该方法里处理任何必要的清理工作,例如解绑定时器,取消网络请求,清理任何在componentDidMount环节创建的DOM元素。

    10.componentDidCatch(error, info)

    • 该函数称为错误边界,捕捉发生在子组件树中任意地方的JavaScript错误,打印错误日志,并且显示回退的用户界面。

    Tip:错误边界只捕捉树中发生在它们之下组件里的错误。一个错误边界并不能捕捉它自己内部的错误。

    11.render()

    • render是一个React组件所必不可少的核心函数(上面的其它函数都不是必须的)。

    Tip:记住,不要在render里面修改state。

    12.React组件更新路径

    在线测试:http://wximg.gtimg.com/shake_tv/test/lifeCycle2113.html

    钩子函数位置 ( 完整code)

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    
    
    class Clock extends React.Component {
      constructor(props) {
        super(props)
          this.state = {
            msg:'hello world'
          }
      }
    
    
    // componentWillMount   组件将要渲染
    componentWillMount(){
      console.log(' CompontWillMount: 组件将要渲染')
    }
    
    // CompontDidMount: 组件渲染完毕
    CompontDidMount(){
      console.log(' CompontDidMount: 组件渲染完毕')
    }
    // compontWillReceiveProps:组件将要接受props数据
    compontWillReceiveProps(){
      console.log(' compontWillReceiveProps:组件将要接受props数据')
    }
    // componentWillReceiveProps : 组件接收到新的state或者props,判断是否更新。 返回布尔值。
    componentWillReceiveProps(){
      console.log(' componentWillReceiveProps: 组件接收到新的state或者props')
    }
    
    // CompontWillUpdate: 组件将要更新
    CompontWillUpdate(){
      console.log(' CompontWillUpdate: 组件将要更新')
    }
    
    // componentDidUpdate组件已经更新
    
    componentDidUpdate(){
      console.log(' ComponentDidUpdate:组件已经更新')
    }
    
    // componentWillUnmount : 组件 将要卸载
    
    componentWillUnmount(){
      console.log(' componentWillUnmount : 组件 将要卸载')
    }
    
              render(){
    
                  return(  
                    <div> 
                      
                    </div>
                  )
              }
    }
    
    
    
      ReactDOM.render(
        <Clock/>,
        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

    测试:使用上面的code, 测试,页面打开的时候:显示 CompontWillMount:组件将要渲染

    点击修改数据的时候: ComponentDidUpdate:组件已经更新。 其他的等待测试。

    
    
    • 1

    补充: 组件的成员和他们的this

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    
    
    class Clock extends React.Component {
    
    // ----------------------分割线----------------------------------------------
      constructor(props) {
        super(props)
          this.state = {
            msg:'hello world'
          }
          console.log(this);// this指向实例
          this.clickEvent = this.clickEvent.bind(this)// 把方法挂载到this组件下
      }
    
    
    // ----------------------分割线----------------------------------------------
    
              render(){
                console.log(this); // this指向实例
                  return(  
                    <div> 
                      {/*  */}
                      <button onClick = {this.clickEvent.bind(this)}>点击修改数据</button>
                      <span>{this.state.msg}</span>
                    </div>)}
    
    // ----------------------分割线----------------------------------------------
                clickEvent(e){
    //没有bing,this= undefind ;加上bing现在this已经指向实例.才能使用实例上的方法。this.setstate
               console.log(this); 
                  // this.setState({
                  //   msg:'修改内容'
                  // })
                }
    // ----------------------分割线----------------------------------------------
    
    } // 组件的下括号
    
    //  上图表明: 组建中三个部分: constructor   render   dom的clickEvent  三个是并列。
    // 正由于是并列的,所以this不统一。  
    //  所以只要保证this是统一实例。 button可以这两中写法。看上图
    
      ReactDOM.render(
        <Clock/>,
        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

    案例: 疫情 中国地图 引入echart

    npm install echarts
    
    import React from 'react';
    import ReactDOM from 'react-dom'; //
    
    var echarts = require('echarts');//该中引入方式默认实在node_modules 中 npm安装
    
    
    
    class Clock extends React.Component {
    // -----------------分割线---------------------------
      constructor(props) {
        super(props)
          this.state = {
            msg:'hello world',
            my_series_data:[5, 20, 36, 10],
            my_xAxis_data:["衬衫", "羊毛衫", "雪纺衫", "没有裤子"]
          }
      }
    // -----------------分割线---------------------------
          componentDidMount() {
            console.log(this); //指向实例
            // 基于准备好的dom,初始化echarts实例
            var myChart = echarts.init(document.getElementById('main'));
            // 绘制图表
            let shuju ={
              title: { text: 'ECharts 入门示例' },
              tooltip: {},
              xAxis: {
                  data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
              },
              yAxis: {},
              series: [{
                  name: '销量',
                  type: 'bar',
                  data: [5, 20, 36, 10, 10, 20]
              }]
          }
              //  拦截原始数据,用自己的数据替换一下
              console.log(shuju);
               shuju.series[0].data = this.state.my_series_data
               shuju.xAxis.data = this.state.my_xAxis_data
    
            myChart.setOption(shuju);  //渲染图表
    
        }
    // -----------------分割线---------------------------
              render(){
                  return(  
                    <div className="myecahrt"> 
                            <h1>我的creact 图表</h1>
                            <div id="main" style={{ width: 400, height: 400 }}></div>
                    </div>)
                    }
    // -----------------分割线---------------------------
    } 
    
    
      ReactDOM.render(
        <Clock/>,
        document.getElementById('root')
      );
    
      // 总结: npm 引入 js  ;data中准备好自己的数据; render中准备好挂载点,
      // ;钩子函数,组件dom渲染上后,寻找dom,初始化echart方法,在渲染前替换自己的的数据。
     
    
    
    
    • 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

    引入echar map地图

    import React from 'react';
    import ReactDOM from 'react-dom'; 
    
    
    import echarts from 'echarts'
    
    import 'echarts/map/js/china';
    
      // require ('echarts/map/js/china')
    
    
    // import ('echarts/map/js/china');  采用该种方法引入 报错 如下:
    // Expected an assignment or function call and instead 
    // saw an expression  no-unused-expressions
    
     class App extends React.Component {
      // export class App extends Component {
        constructor(props) {
            super(props);
            this.state = {
            
                data:[
                    {
                        name: "南海诸岛",
                        value: 0
                    },
                    {
                        name: '北京',
                        value: 20
                    },
                    {
                        name: '天津',
                        value: 30
                    },
                    {
                        name: '上海',
                        value: 229
                    },
                    {
                        name: '重庆',
                        value: 59
                    },
                    {
                        name: '河北',
                        value: 190
                    },
                    {
                        name: '河南',
                        value: 300
                    },
                    {
                        name: '云南',
                        value: 20
                    },
                    {
                        name: '辽宁',
                        value: 40
                    },
                    {
                        name: '黑龙江',
                        value: 37
                    },
                    {
                        name: '湖南',
                        value: 180
                    },
                    {
                        name: '安徽',
                        value: 0
                    },
                    {
                        name: '山东',
                        value: 67
                    },
                    {
                        name: '新疆',
                        value: 10
                    },
                    {
                        name: '江苏',
                        value: 0
                    },
                    {
                        name: '浙江',
                        value: 0
                    },
                    {
                        name: '江西',
                        value: 0
                    },
                    {
                        name: '湖北',
                        value: 0
                    },
                    {
                        name: '广西',
                        value: 0
                    },
                    {
                        name: '甘肃',
                        value: 0
                    },
                    {
                        name: '山西',
                        value: 0
                    },
                    {
                        name: '内蒙古',
                        value: 89
                    },
                    {
                        name: '陕西',
                        value: 0
                    },
                    {
                        name: '吉林',
                        value: 0
                    },
                    {
                        name: '福建',
                        value: 66
                    },
                    {
                        name: '贵州',
                        value: 0
                    },
                    {
                        name: '广东',
                        value: 330
                    },
                    {
                        name: '青海',
                        value: 0
                    },
                    {
                        name: '西藏',
                        value: 74
                    },
                    {
                        name: '四川',
                        value: 601
                    },
                    {
                        name: '宁夏',
                        value: 0
                    },
                    {
                        name: '海南',
                        value: 45
                    },
                    {
                        name: '台湾',
                        value: 23
                    },
                    {
                        name: '香港',
                        value: 0
                    },
                    {
                        name: '澳门',
                        value: 0
                    }
                ]
           
    
            }
        }
    
        componentDidMount(){
            this.initMap();
        }
        
        //初始化地图
    
        initMap = () => {
            let myChart = echarts.init(document.getElementById('myMap'));
            let option = {
                tooltip: {
                    formatter: function (e , t, n) {
                        return e.seriesName + "
    " + e.name + ":" + e.value } }, visualMap: { min: 0, max: 1000, right: 26, bottom: 40, showLabel: !0, pieces: [{ gt: 500, label: "500家以上", color: "#ED5351" }, { gte: 200, lte: 500, label: "201-500家", color: "#3B5A97" }, { gte: 100, lt: 200, label: "101-200家", color: "#59D9A5" }, { gt: 51, lte: 100, label: "51-100家", color: "#F6C021" }, { label: "1-50家", gt: 0, lte: 50, color: "#6DCAEC" } ], show: !0 }, geo: { map: "china", roam: !1, scaleLimit: { min: 1, max: 2 }, zoom: 1.13, layoutCenter: ['30%', '30%'], //地图中心在屏幕中的位置 label: { normal: { show: !0, fontSize: "14", color: "rgba(0,0,0,0.7)" } }, itemStyle: { normal: { borderColor: "rgba(0, 0, 0, 0.2)" }, emphasis: { areaColor: "#F5DEB3", shadowOffsetX: 0, shadowOffsetY: 0, borderWidth: 0 } } }, series: [{ name: "客户统计", type: "map", geoIndex: 0, data: this.state.data, areaColor: '#0FB8F0' }] }; myChart.setOption(option); window.addEventListener("resize", function () { myChart.resize(); }); } render(){ return (
    {"height":"800px"}} >
    ) } } ReactDOM.render( , 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
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277

    16 表单和图表 seach案例

    涉及点: 父子传值, 常规dom渲染理解为jsx对象,map循环,

    子页面的绑定事件,模块导出。

    index.js

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    
    import Search from './component/search';
    
    class Clock extends React.Component {
    
      constructor(props) {
        super(props)
       this.state = {
         listarr : [
           {
             id:1,
              title:'第一个标题1',
              cont:'我是内容1'
           },
           {
            id:2,
              title:'第一个标题2',
              cont:'我是内容2'
           }
         ]
       }
      }
              render() {
                let listArr = this.state.listarr.map((itme,index)=>{
                  return(
                 <div key = {index} className = {'item'+index}>
                        <li>{itme.title}</li>
                        <p>{itme.cont}</p>
                 </div>
                
                  )
                })
                
             
    
                  return(  
              
                    <div> 
                      <Search alldata = {this.state.listarr}></Search>
                        <ul>
                              {listArr}
                        </ul>
                    </div>
                  )}
    }
    
      ReactDOM.render(
        <Clock/> ,
        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

    search.js页面

    import React from 'react';
    
    class Search extends React.Component {
    
        constructor(props) {
          super(props)
         this.state = {
            value:undefined,
            result:":查询结果"
         }
        }
                    render() {
                        return(   
                            <div className= 'search'> 
                                  <input type="text" onKeyDown = {this.serchEvent.bind(this)}  placeholder='请输入' 
                                //   value = {this.state.value}
                                //   onChange = {this.chengeEvent.bind(this)}
    
                                  />
                                        <div>
                                            <h2>查询结果</h2>
                                            <div>
                                                这是查询结果 search
                                                {this.state.result}
                                            </div>
                                        </div>
                             
                            </div>
                        )}
    
          serchEvent(e){
                // let a = this.props.alldata[e.target.value]
                if(e.keyCode === 13){
     
                    if(this.props.alldata[e.target.value]){
                        this.setState({
                            result :(<h2>{this.props.alldata[e.target.value].cont}</h2> )
                        })
                    }else{
                        this.setState({
                                result :(<h2>只有两条数据啊</h2> )
                      
                        })
                    }  
                }
          }
    
          chengeEvent(e){
    
    // console.log(e.target.value);
                this.setState({
                    // value:e.target.value
                })
          }
        }
        
        export default Search;
    
    
    • 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

    17 React 的ajax案例

    Ajax + React + axios + Express 案例

    17-1 服务端

    环境准备

    常规准备
    1. npm init    生成package.son文件 记录以来信息
    2. npm i webpack --save-dev   安装webpack  生成node_modules 打包依赖文件  18M大小
    项目使用的插件和框架准备
    
    3.npm install express --save      --save是保存版本信息。其中主要封装的是http。   
    4.  npm install --global  n         odemon热加载
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    新建index.js

    // 0 安装 
    // 1 引包
    const express = require('express')  // 引包
    
    const app = express() //调用
    // app.get('/', (req, res) => res.send('Hello World!'))  //res.send 这里 变了
    
    app.get('/', function(req, res){
            res.send('Hello World!')
    })
    
      // 再写一个
    app.get('/app', function(req, res){
            res.send('您好我是:app')
    })
    
    // app.listen(3000, () => console.log('running...'))
    app.listen(3000, function(){
            console.log('running...')
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    启动服务:

    cmd 命令行中输入: nodemon app.js 
    
    ok项目启动 浏览器打开 
    基本的服务搭建完成
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    项目使用的插件

    axios

    npm install axios --save
    
    注意引入index.js
    
    
    • 1
    • 2
    • 3
    • 4

    asynchronous 异步

    疫情接口( 仅学习使用)

    https://voice.baidu.com/newpneumonia/get?target=trend&isCaseIn=0&stage=publish&callback=jsonp_1595142630965_83751(jsonp格式转换json格式)

    app.get('/api', async function(req, res){
          //解决跨域问题
    //   res.json({name:'lyx'})
    let url = 'https://voice.baidu.com/newpneumonia/get?target=trend&isCaseIn=0&stage=publish&callback=jsonp_1595142630965_83751'
      let resdata = await axios.get(url)
            let data =resdata.data;
            // res.send(data)
           res.json(data) 
        
    })
    
    打开页面,可以看到数据
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    17-2 前端

    1. 初始化react项目包

      包含操作: npm init /npm webpack / 外加两个文件夹/ md说明文档/ 就是一个快捷操作

     create-react-app reactapp
    
    
    • 1
    • 2
    1. axios 前端安装 axiox 都自己的node_modules
    npm install axios --save
    
    注意引入app.js
    const axios = require('axios')  
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    前端访问疫情接口:

    		  async	componentWillMount(){
    				console.log(0)
    				// axios.get()
    let url = 'https://voice.baidu.com/newpneumonia/get?target=trend&isCaseIn=0&stage=publish&callback=jsonp_1595142630965_83751'
     let resdata = await axios.get(url)
     let data =resdata.data;
     console.log(data);
    			          }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    跨域: 解决

     这就是搭建后台的原因:
    
    async	 componentWillMount(){
            let url = 'http://localhost:4000/api'
             let resdata = await axios.get(url)
             let data_ = resdata.data.features
    
              this.setState({
                Newslistdata:data_
              })
    
            console.log('前台返回第一层数据',data_);	 
            }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    页面结构

    1. 这里的4个tab切换,不是路由,而是在主页面中引入了4个子页面。 放在主页面的cont中,flex横向排列。

      点击tab,控制父盒子的定位左侧移动。

      2.实现点击tab bar动画: state准备:tabIndex,条件渲染tab,tab 设置点击事件,this.setState({})方式修改tabIndex,dom会根据数据变化,自动重新渲染。 4个tab移动意识一样。

      1. new页面的数据,为自己请求的数据。

      2. 图片的引入和使用: 引入后的变量 : src = {变量}

        import Bannerimg from ‘./assets/img/newbanner.jpg’;

        图片
    import React from 'react';
    import './assets/css/styls.css';
    
    import NewsCom from './new';
    const axios = require('axios')  
    
    function Map() {
    	return(
    		

    我是map组件

    ) } class App extends React.Component{ constructor(props){ super(props) this.state = { msg:'lyx', navlist:['疫情地图','最新进展','广州疫情','新闻内容'], tabIndex:0, barStyle:{ "left":"22px" }, contStyle:{ "transform" :"translate(0,0)" } } } // ------------------------------------------ render(){ var navjsx= this.state.navlist.map((item,index)=>{ if(index === this.state.tabIndex){ return(
    {this.tabClickEvent(index)}} key ={index}> {item}
    ) }else{ return(
    {this.tabClickEvent(index)}} key ={index}> {item}
    ) } }) return (
    {navjsx}
    ); } // ---------- ---------- tabClickEvent = (index)=>{ this.setState({ barStyle:{ "left":(index*88+22)+"px" }, contStyle:{ "transform" :`translate(${-index*375}px,0)` } }) } } 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
    • 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

    解析:

    18 插槽

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

    原理: 在父页面 引入的子组件组件中写入的HTML, 会挂载到放到子组件 props中。

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    
    
    
    class Children extends React.Component {
    
      constructor(props) {
        super(props)
       this.state = {
       
       }}
    
            render(){
              console.log(this);
          //2. 在子元素的this。props中则挂载了插槽了的数据。 属性值和jsx,
          // 所以可以实现条件渲染在自己的dom中。
              return(
                <div className = 'Children-dom'>
                    <h1>我是chidren</h1>
                {this.props.children}
                </div> 
              )
            }
    
    }
    // --------------------
    
    class Clock extends React.Component {
      constructor(props) {
        super(props)
       this.state = {
       fatherList : 'i is from father'
       }
      }
              render() {
               
                  return(  
                    <div>    
                      {this.props.children}
                          <h1>我是h1</h1>
                          <Children>  
                 {/* 1. 插槽传值:在字标签中可以传入标签,dom 标签中的属性值,和state中的数据。 */}
    
                            <h1 data-id ='1'>我是parent的插槽 头部</h1>
                            <h1 data-id ='2'>我是parent的插槽 尾部</h1>
                              <span>  {this.state.fatherList}</span>
                          </Children>
                    </div>
                  )}
    
    }
    
    
      ReactDOM.render(
        <Clock>
        </Clock> ,
        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

    19 路由

    概念:

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

    安装:

    npm install react-router-dom --save       (--save保存版本信息) 
                                                  "react-router-dom": "^5.2.0",
    
    
    • 1
    • 2
    • 3

    ReaterRouter : 三大组件

    Router: 所有路由租金的跟组件(底层组件),包裹路由规则的最外层容器。

    Route:路由规则匹配组件,显示当前规则对应的组件。

    Link: 路由跳转的组件。

    注意: 如果要精确匹配,那么可以在route上设置 exacct 属性。(注意单词adj. 准确的,精密的;精确的)

    路由的两种引入:

    hash 模式

    #/ #号就是hash的标志。 不发送请求

    import { HashRouter as Router, Route , Link} from 'react-router-dom'
    
    
    • 1
    • 2

    history 模式

    /后边导向 需要后端配合

      引入
    import {BrowserRouter as Router, Route , Link} from 'react-router-dom'
    
    
    
    • 1
    • 2
    • 3
    • 4

    总结:

    basename 设根路径

    route 映射路由和组件 关系

    link 相当于a标签跳转

    0. exact 精准匹配。

    第一种: 当有link标签时, 加载link中。
    第二种: 没有link标签,只有route 标签时,加在route中。
    
     <Link to = '/product' exact>产品页</Link>
    <Route path =  "/"    component = { ()=> (   <div> 首页1</div>) }></Route>
    
    
    
    <Route path =  "/"  exact  component = { ()=> (   <div> 首页1</div>) }></Route>
                                                   
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    基本的路由模式 code

    1. 常规的路由link跳转 和传值

    APP.js 组件页面 挂载到index.js 主页面中

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    import {BrowserRouter as Router, Link, Route} from 'react-router-dom'
    
    
    function Me(props){
      console.log(props);
      return(
            <h1>Me</h1>
      )
    }
    
    function Home(props){
      console.log(props);
      return(
            <h1>Home</h1>
      )
    }
    
    
    
    function Produc(props){
      console.log(props);
      return(
            <h1>Produc</h1>
      )
    }
    
    
      class App extends React.Component {
      constructor(props) {
        super(props)
       this.state = {
      
       }
      }
        render(){
          return(   
    
      <div id = 'app'>    
               <div> 所有页面都显示的普通页面</div>
       
       
             <Router >   
            
             <div className = 'nav'>
          
                 <Link to = { { pathname:"/",search:"?sername=admin",hash:"#abc",state:{msg:"helloworld"}} }>Home</Link>
                 <Link to = '/product'>产品页</Link>
                 <Link to = '/me'>个人中心</Link>
             </div>
       
                 <Route path = "/" exact component = {Home}></Route>
                 <Route path =  "/product" component = {Produc}></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
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    Link to = { 变量}
             <Router >   
             <div className = 'nav'>
                 <Link to = { { pathname:"/",search:"?sername=admin",hash:"#abc",state:                                       {msg:"helloworld"}} }>Home</Link>
             
             </div>
                 <Route path = "/" exact component = {Home}></Route>
             </Router> 
    
    1. link to  后面的path和route标签,映射关系。
    2. exact 精准匹配。  否则 /me 页面会显示  /的页面。
    3. link传递的值。可以在组件中收到
    
    
            function Home(props){
              console.log(props);
              return(
                    <h1>Home</h1>
              )
            }
    
    点击会自动拼接
    http://localhost:3000/?sername=admin#abc
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2 path 传值

    通过路由标签,link传值, route : 键值, 组件中props对象中可以看到params下的值。

            <Router >   
             <div className = 'nav'>
                <Link to = '/me/12345' replace >个人中心</Link>
             </div>
                <Route path =  "/me/:id"    component = {Me}></Route>
             </Router> 
    
    浏览器地址
    http://localhost:3000/me/12345
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3. Link 的 replace 路由切换跳转

    替换栈 。 使用方法: 直接在Link 标签后内添加 replace 替换 属性。

            <Router >   
             <div className = 'nav'>
                 <Link to = '/me' replace >个人中心</Link>
             </div>
                 <Route path =  "/me"    component = {Me}></Route>
             </Router> 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    路由跳转,replace / push 区别

     push: a-b-c 可以回到上一级
     例: this.props.history.push('路由地址')
    
    
    • 1
    • 2
    • 3
    replace: a-b-c 回不到上一级 适用于登录后,不需要重新回到登页面
     例: this.props.history.replace('路由地址')
    
    
    • 1
    • 2
    • 3

    4 重定向组件

    形式也是一个组件,所以也有props 对象。

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

    引入 Redirect 方法

    import {BrowserRouter as Router, Link, Route, Redirect} from 'react-router-dom'
    
    
    • 1
    • 2

    原理:

    假设 form表单登录的时候, 设置访问FormCom() 组件,这个组件就是登录页面,点击提交,

    组件内设置 ajax请求,获取用户权限,携带信息,跳转LoginInfo 组件, 组件内 标签 ,跳转到 登录或者是 首页。

    import React from 'react';
    // import ReactDOM from 'react-dom';
    
    import {BrowserRouter as Router, Link, Route, Redirect} from 'react-router-dom'
    
    
    
    function LoginInfo(props){    //重定向组件 
    
      if(props.location.state.login_state == 'success'){
        // 如果成功 定向到admin页面
        return <Redirect to = "/admin"> </Redirect> 
      }else{
        return <Redirect to = "/login"></Redirect> 
      }
    }
    
    
    function FormCom(){
       let dataobj = {
         pathname:"LoginInfo",
         state:{
           login_state:'success'
         }
       }
    
        return(
    <div>
      <h1>表单验证模拟</h1>
        <Link to = {dataobj }>点击跳转至LoginInfo控制组件</Link>
        
    </div>
        )
    }
    
      class App extends React.Component {
        render(){
          return(   
    
                <div id = 'app'> 
              
             <Router >   
              <Route path =  "/"  exact  component = { ()=> (   <div> 首页1</div>) }></Route>
              <Route path =  "/form" exact  component = { FormCom }></Route>
              <Route path =  "/login" exact  component = { ()=> (   <div> login请重新登陆                           </div>) }>
              </Route>
              <Route path =  "/LoginInfo" exact  component = { LoginInfo }></Route>
              <Route path =  "/admin" exact   component = { ()=> (   <div> admin登录成功到                              admin</div>) }>
            </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
    • 59
    • 60
    • 61
    • 62
    • 63

    5 Switch (n. 开关) 匹配 only one

    应用场景:

    路由会一直匹配,直到查找完所有的路由映射。
    
    1.假设没有exact 精准匹配, 进入home 首页也会显示。
     <Route path =  "/" 
     <Route path =  "/home" 
    2.有exact 精准匹配,碰到两个path相同的,又会同时显示两个页面内容。
     <Route path =  "/"  exact  component = { ()=> (   <div> 首页1</div>) }></Route>  
      <Route path =  "/"  exact  component = { ()=> (   <div> 首页1</div>) }></Route>
     
                                                     
     Switch 作用: 匹配一条route,符合要求,就停止匹配。                                                                                          
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    使用方式:

    引入  Switch 方法  注意模块都是首字母大写
    
    import {BrowserRouter as Router, Link, Route, Redirect, Switch} from 'react-router-dom'
    
    
    包裹route 使用。
       
               
               (   
    首页1
    ) }>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    6 编程式路由 js控制

    1. push ( ) 跳转

    子页面,点击跳转同时携带数据, 传值

    
    
    class Children extends React.Component {
    
      render(){
        return(   
              <div id = 'Children'>    
            <button onClick = { this.clickEvent}>  跳转到首页</button>
                我是 Children
            </div>
        )
      }
            clickEvent=()=>{  
                console.log(this.props.history.push("/",{name:"这是chilren传递的数据"}))
              }
              // push( ) 接受两个参数  第一个时路由path , 第二个是: 可以页面传值  目标组件的 props中的location-state 下挂载
    
      }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    replace
    go
    clickEvent=()=>{  
              //  this.props.history.push("/",{name:"这是chilren传递的数据"})
              //  this.props.history.replace("/",{name:"这是chilren传递的数据"})
              this.props.history.go(-1)  //正数前进,负数后退。 历史堆栈中要有数据,否则不能跳转。
    
              }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    7 动态路由

    解析:

    正常老说: path = “/” 只能在 localhost:3000/ 时可以访问。 不能加参数

    path = “/:id” 这种, 后边可以加参数,变化的参数也可以。 动态。

    同样 props中可以查看数据

    <Route path =  "/:id"  exact  component = { shouye }></Route>
    
    
    
    • 1
    • 2
    • 3
  • 相关阅读:
    sample函数—R语言
    基于nodejs的电影交流网站-计算机毕业设计
    Mybatis面试题(三十三道)
    记录socket的使用 | TCP/IP协议下服务器与客户端之间传送数据 | java学习笔记
    HarmonyOS列表组件
    jdbc 数据源(DruidDataSourceFactory)连接池 —— druid
    基于java图书馆借阅管理系统获取(java毕业设计)
    MySQL数据库增删改查进阶 — 聚合查询、分组查询、联合查询
    【注释和反射】获取class类实例的方法
    保姆级 C++ 学习路线
  • 原文地址:https://blog.csdn.net/lyxkgc/article/details/134038815