react

 

pc端开发 先统一所有浏览器的样式

 

https://meyerweb.com/eric/tools/css/reset/

 

 

安装react-cli  

npx create-react-app my-react-app

 

安装 axios

yarn add axios --save

axios的使用 及 react代理服务器的配置

配置单个代理

import React, { Component } from 'react'
import axios from 'axios';

import './index.scss';
export default class TodoList extends Component {
     //发送axios 获取数据
    getAxiosState=()=>{
        /*
        记住添加http://   端口号还是本身3000的端口号   
        在package中添加代理 请求代理服务器3000转发到5000端口的服务器
        "proxy":"http://localhost:5000"
        */
        axios.get('http://localhost:3000/login')
        .then(function (response) {
          console.log(response);
        })
        .catch(function (error) {
          console.log(error);
        });
    }
    render() {
        return (
            <div >
                {/* 发送axios请求 */}
                <button onClick={this.getAxiosState}>点击获取数据</button>
            </div>
        )
    }
}
View Code

 配置多个代理  就不许用在package中配置,需要在src文件下建立一个文件setupProxy.js(不允许改名)

setupProxy.js配置

const proxy=require('http-proxy-middleware')
module.exports = function (app) {
    app.use(
        proxy.createProxyMiddleware('/api1', { //遇/api前缀的请求,就会出发该代理配置
            target: 'http://localhost:5000', //服务器转发目标
            changeOrigin: true, //控制服务器收到的请求头中的‘HOST’值
            /*
            changeOrigin:trur 服务器 收到的请求头的host就是5000开头
            changeOrigin:false 服务器 收到的请求头的host就是3000开头(默认false)
            我们一般设置为true
            */
            pathRewrite: {
                '^/api1': ''
            } //重写请求路径  将/api1的路径替换成空字符串(必须配置)
        }),
        proxy.createProxyMiddleware('/api2', { //遇/api前缀的请求,就会出发该代理配置
            target: 'http://localhost:5001', //服务器转发目标
            changeOrigin: true, //控制服务器收到的请求头中的‘HOST’值
            pathRewrite: {
                '^/api2': ''
            } //重写请求路径
        })
    )
}
View Code

用法

import React, { Component } from 'react'
import axios from 'axios';

import './index.scss';
export default class TodoList extends Component {
     //发送axios 获取数据
    getAxiosState=()=>{
        /*
        记住添加http://   端口号还是本身3000的端口号   
        在package中添加代理 请求代理服务器3000转发到5000端口的服务器
        只有3000端口没有的资源才会找5000端口的服务器要
        必须带上setupProxy.js中的自己设置的/api1 前缀
        */
        axios.get('http://localhost:3000/api1/login')
        .then(function (response) {
          console.log(response);
        })
        .catch(function (error) {
          console.log(error);
        });
    }

    //第二个代理请求
    getAxiosState1=()=>{
        axios.get('http://localhost:3000/api2/cors')
        .then(function (response) {
          console.log(response);
        })
        .catch(function (error) {
          console.log(error);
        });
    }
    render() {
        return (
            <div >
                {/* 发送axios请求 */}
                <button onClick={this.getAxiosState}>点击获取数据0</button>
                <button onClick={this.getAxiosState1}>点击获取数据1</button>
            </div>
        )
    }
}
View Code

 

使用fatch发送 请求(特点  不许用下载安装   老版本浏览器可能不支持)

promise写法

   getMsg=()=>{
        /*
        fatch用法 window自带的方法
        fatch第一个then 返回的res是请求服务器成功,res原型链上的json()方法返回的是一个promise状态
        之后才可以then()获取成功失败的参数
        */
        fetch(`http://localhost:3000/api1/login`)
        //  res中原型上的json()方法返回的是promise()pending的一个状态
        // .then(res=>{console.log(res.json());return res.json()})
        .then(res=>res.json())
        .then((data)=>console.log(data)).catch(err=>{
            console.log(err)
        })
    }
View Code

ES7 async await写法

    //async await 优化 promise()写法
    getMsg = async () => {
        try { 
            const res = await fetch(`http://localhost:3000/api1/login`);
            const data = await res.json();
            console.log(data,'success');
        } catch (e) {
            console.log(e,'error');
        }
    }
View Code

 

 

 

安装 styled-components  (使各个模块的css独立出来) (如果使用scss之类的就不许用这样css模块化)

yarn add styled-components

第一步  把css文件改成js文件

第二部  import {createGlobalStyle } from 'styled-components';  (全局样式组件方法)

 

style.js
//1引入全局样式方法
import {createGlobalStyle } from 'styled-components';

//2定义并暴露全局样式
export const GlobalStyled =createGlobalStyle`
  body{
    margin:0;
    padding:0;
    background:blue;
  }
APP.js
//3引入全局样式 并以组件的形式使用
import {GlobalStyled} from './style'

function App() {
  return (
    <div className="App">
      <GlobalStyled/>
      hello world
    </div>
  );
}

export default App;

 第三部  import styled from 'styled-components';  (局部样式组件方法)

common公用的组件 中的index.js

import styled from 'styled-components';

export const HeaderWrapper=styled.div`
    height:56px;
    background:red;
`

common公用的组件的样式

import React,{Component} from 'react';
import {HeaderWrapper} from './style';
class Header extends Component{
    render(){
        return (
            <HeaderWrapper>hello world</HeaderWrapper>
        )
    }
}

export default Header;

 

 

 

 

安装scss 

yarn add node-sass

 scss用法

import React ,{Component} from 'react';
import './index.scss';

class TodoList extends Component{
    render(){
        return (
            <div>
                <ul>
                    <li>hello world</li>
                    <li>happy</li>
                </ul>
            </div>
        )
    }
}


export default TodoList;
View Code

 

 安装ant-design  PC端

yarn add antd --save

 ant-design库的用法

import React ,{Component} from 'react';
import 'antd/dist/antd.min.css';
import './index.scss';
import {Button} from 'antd';
class TodoList extends Component{
    render(){
        return (
            <div>
                <Button type="primary" className="btn">Button</Button>
            </div>
        )
    }
}


export default TodoList;
View Code

 

 安装 antd-mobile  移动端

yarn add antd-mobile@next

使用 不需要引入样式  antd-mobile会自动加载样式

import React, { Component } from 'react'
import { Button } from 'antd-mobile'
export default class Login extends Component {
    render() {
        return (
            <div>
                <Button color='primary'>Primary</Button>
            </div>
        )
    }
}
View Code

 

 

安装prop-types库   

yarn add  prop-types --save

prop-types 库的用法

import React,{Component} from 'react';
//1引入prop-types库
import PropTypes from 'prop-types';

class Child extends Component{
    constructor(props){
        super(props);
        this.state={
            item:this.props.content
        }

    this.handleClick=this.handleClick.bind(this);
    }
    handleClick(){
        this.props.delmethods(this.props.index)
    }
    render(){
        return (
            <div onClick={this.handleClick}>
                {this.state.item}
            </div>
        )
    }
}

//2数据类型校验
Child.propTypes= {
    // 表示content类型要是string 且必须要传递
    content:PropTypes.string.isRequired,
    delmethods:PropTypes.func,
    index:PropTypes.index,
    test:PropTypes.string
}

//3如果父组件没传递数据 可以定义默认值
Child.defaultProps={
    test:'hello'
}

export default Child;
View Code

 

 

shouldComponentUpdate用法

shouldComponentUpdate(nextProps,nextState){
    if(nextProps.content!==this.props.content){
          return true;
  } else{
       return false;  
    }
}
View Code

 

安装react-redux

yarn add react-redux --save

react-redux的用法

 

用法 主要就两部
- 第一步 被Provider包裹的子组件 内部可以直接调用store中的数据
- 第二部 connect(mapStateToProps,mapDispatchToProps)(TodoList)
- mapStateToProps 主要负责 将store中的state数据映射到TodoList的props属性中
- mapDidpatchToProps 主要负责将props中的方法可以通过dispatch方法发送action到store中的reducer内 修改store中的state数据
挂载节点 第一步使用Provider组件
index.js

 

 

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import reportWebVitals from './reportWebVitals';
import TodoList from './TodoList/index';
import store from './store/index';

//Provider组件  可以是内部的所有子组件都可以获得store的数据
import {Provider} from 'react-redux';

const App=(
  <Provider store={store}>
    <TodoList></TodoList>
  </Provider>
)


ReactDOM.render(
  App,
  document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
View Code

 

store中的index.js

//引入redux  createStore  创建store
//applyMiddleware 方法允许redux 使用中间件
import { createStore, applyMiddleware, compose } from "redux";
import reducer from "./reducer";
import thunk from "redux-thunk";

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
  ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
      // Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
    })
  : compose;

const enhancer = composeEnhancers(
  applyMiddleware(thunk)
  // other store enhancers if any
);
//创建store  并把reducer存入store中
const store = createStore(
  reducer,
  enhancer
//   applyMiddleware(thunk)
  // rudex dev tools  chrome 插件 使用
  // window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);

export default store;
View Code

store中的reducer.js

const defaultState={
    inputValue:'',
    list:[1,3,4,5,5]
}

export default (state=defaultState,action)=>{
    if(action.type==='change_input_value'){
        const newState=JSON.parse(JSON.stringify(state));
        newState.inputValue=action.value;
        console.log(newState)
        return newState;
    }
    if(action.type==='add_todo_list'){
        const newState=JSON.parse(JSON.stringify(state));
        if(newState.inputValue===''){
            return newState;
        }
        newState.list.push(newState.inputValue);
        newState.inputValue='';
        return newState;
    }
    if(action.type==="delete_todo_list"){
        console.log(1)
        const newState=JSON.parse(JSON.stringify(state));
        newState.list.splice(action.value,1);
        return newState;
    }
    return state;
}
View Code

TodoList组件中的index.js

import React, { Component } from "react";
import { connect } from "react-redux";

//无状态组件是一个函数

const TodoList = (props) => {
  const { inputValue, changeInputValue, handleClick, handleDel } = props;
  return (
    <div>
      <div>
        <input type="text" onChange={changeInputValue} value={inputValue} />
        <button type="button" className="btn" onClick={handleClick}>
          输入
        </button>
      </div>
      <ul className="list">
        {props.list.map((item, index) => {
          return (
            <li onClick={handleDel.bind(this, index)} key={index}>
              {item}
            </li>
          );
        })}
      </ul>
    </div>
  );
};

// class TodoList extends Component {
//   constructor(props) {
//     super(props);
//   }
//   render() {
//       const { inputValue, changeInputValue, handleClick, handleDel } = this.props;
//       return (
//       <div>
//         <div>
//           <input type="text" onChange={changeInputValue} value={inputValue} />
//           <button type="button" className="btn" onClick={handleClick}>
//             输入
//           </button>
//         </div>
//         <ul className="list">
//           {this.props.list.map((item, index) => {
//             return (
//               <li onClick={handleDel.bind(this,index)} key={index}>
//                 {item}
//               </li>
//             );
//           })}
//         </ul>
//       </div>
//     );
//   }
// }

const mapStateToProps = (state) => {
  return {
    inputValue: state.inputValue,
    list: state.list,
  };
};

const mapDispatchToprops = (dispatch) => {
  return {
    changeInputValue(e) {
      const action = {
        type: "change_input_value",
        value: e.target.value,
      };
      // console.log(e.target.value)
      dispatch(action);
    },
    handleClick() {
      const action = {
        type: "add_todo_list",
      };
      dispatch(action);
    },
    handleDel(index) {
      const action = {
        type: "delete_todo_list",
        value: index,
      };
      dispatch(action);
    },
  };
};

//connect(mapStateToProps,mapDispatchToprops) 方法的作用使TodoList和store链接
//并按照mapStateToProps的规则下将store中的数据映射到TodoList的props中
//store.dispatch映射到TodoList组件的props上 可以让props上的方法能够调用dispatch来操作store中的数据
export default connect(mapStateToProps, mapDispatchToprops)(TodoList);
View Code

 

Ref的使用

第一种 字符串类写法  (不推荐  现在还可以使用 将来可能废弃 )

第二种 回调函数式写法(最为推荐)

import React, { Component } from 'react'

export default class home extends Component {
    showData=(c)=>{
        //函数
        this.input2=c;
        console.log(this.input2)
    }
    render() {
        return (
            <div>
                {/* ref 方式1 string形式   目前还可以用 未来可能废弃 */}
                <button onClick={()=>{console.log(this.refs.input1)}}>点击提示</button>
                <input ref='input1' type="text" onBlur={this.handleClick} placeholder='左侧侧提示' />
                {/* ref 方式2  callback 形式 */}
                <button onClick={()=>{console.log(this.input2)}}>点击提示</button>
                {/* <input type="text" placeholder='右侧提示' ref={(currentNode)=>{this.input2=currentNode}} /> */}
                {/* 箭头函数简写(内联函数写法,更新时会出发两次  功能不收影响  第一次值为null  第二次才为Dom节点;(每次函数执行完毕后会清空传入的currentNode 之后在重新执行)) */}
                {/* <input type="text" placeholder='右侧提示' ref={(c)=>this.input2=c} /> */}
                {/* 推荐写法 */}
                <input type="text" placeholder='右侧提示' ref={this.showData} />
            </div>
        )
    }
}
View Code

第三种 使用最新Api  React.createRef 调用后返回一个容器,改容器可以存储ref所表示的节点

import React, { Component } from 'react'

export default class home extends Component {
    //1调用React.createRef()创造myRef容器(单个容器)
    myRef1=React.createRef();
    myRef2=React.createRef();
    //3 使用ref容器的方式
    showDate=()=>{
        console.log(this.myRef1);
        console.log(this.myRef2);
    }
    render() {
        return (
            <div>

                <button onClick={this.showDate}>点击提示</button>
                {/* ref 方式3 Api React.create()创建ref容器形式  */}
                <input type="text" placeholder='右侧提示' ref={this.myRef1} />
                <input type="text" placeholder='右侧提示' ref={this.myRef2} />
            </div>
        )
    }
}
View Code

 

 

 受控组件和非受控组件

// 非受控组件  
// 受控组件的作用 可以少写ref 随用随取 
import React, { Component } from 'react'

export default class Login extends Component {

    state={
        username:'',
        password:''
    }

    //非受控组件使用ref
    LoginUser = (event) => {
        const { username, password } = this
        event.preventDefault();//阻止表单默认提交
        console.log(`你的账号是${username.value},你的密码是${password.value}`)
    }

    //受控组件方法 实时获取状态
    saveUserName = (e) => {
        console.log(e)
        this.setState({
            username: e.target.value
        })
    }
    savePassword = (e) => {
        this.setState({
            password:e.target.value
        })
    }
    render() {
        return (
            <div>
                {/* 非受控组件 */}
                <form action="" onSubmit={this.LoginUser}>
                    <div className="item">
                        <label htmlFor="">账号</label>
                        <input type="text" placeholder='请输入账号' ref={c => this.username = c} />
                    </div>
                    <div className="item">
                        <label htmlFor="">密码</label>
                        <input type="password" placeholder='请输入密码' ref={c => this.password = c} />
                    </div>
                    <div className="item">
                        <button>登录</button>
                    </div>
                </form>
                {/* 受控组件 */}
                <form action="" onSubmit={this.LoginUser}>
                    <div className="item">
                        <label htmlFor="">账号</label>
                        <input type="text" placeholder='请输入账号' onChange={this.saveUserName} />
                    </div>
                    <div className="item">
                        <label htmlFor="">密码</label>
                        <input type="password" placeholder='请输入密码' onChange={this.savePassword} />
                    </div>
                    <div className="item">
                        <button>登录</button>
                    </div>
                </form>
            </div>
        )
    }
}
View Code

 

 高阶函数及柯理化函数应用(简写表单绑定数据)

import React, { Component } from 'react'

export default class Reg extends Component {
    /*
    高阶函数:如果一个函数符合下面两个规范中的任何一个,那该函数就是高阶函数
    1 若A函数,接收的参数是一个函数,那么A久可以称之为高阶函数
    2 若A函数,调用的返回值依然是一个函数,那么A久可以称之为高阶函数

    常见的高阶函数:Promise,setTimeout,arr.map()等
    
    函数的柯理化 :通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式;
    
    
    */ 
    LoginUser = (e) => {
        e.preventDefault();
    }

    //函数的柯理化
    saveFormDate=(dataType)=>{
        const that=this;
        return (event)=>{
            //[]会解析变量
            that.setState({
                [dataType]:event.target.value
            })
        }
    }

    notSaveFormDate=(dataType,e)=>{
        this.setState({
            [dataType]:e.target.value
        })
    }
    render() {
        return (
            <div>
                {/* 使用柯理化  */}
                <form action="" onSubmit={this.LoginUser}>
                    <div className="item">
                        <label htmlFor="">账号</label>
                        <input type="text" onChange={this.saveFormDate('username')} placeholder='账号' />
                    </div>
                    <div className="item"><label htmlFor="">密码</label>
                        <input type="password" placeholder='密码' onChange={this.saveFormDate('password')}/>
                    </div>
                    <div className="item"><button className="btn">登录</button></div>
                </form>

                {/*不使用柯理化 (通用方法) */}
                   <form action="" onSubmit={this.LoginUser}>
                    <div className="item">
                        <label htmlFor="">账号</label>
                        <input type="text" onChange={(e)=>{this.notSaveFormDate('username',e)}} placeholder='账号' />
                    </div>
                    <div className="item"><label htmlFor="">密码</label>
                        <input type="password" placeholder='密码' onChange={(e)=>{this.notSaveFormDate('password',e)}}/>
                    </div>
                    <div className="item"><button className="btn">登录</button></div>
                </form>
            </div>
        )
    }
}
View Code

 

react 生命周期 旧

 

 

 

 

 

新生命周期

 

react新生命周期与旧生命周期对比

 

 diff 算法

 

 

 虚拟DOM相关

 

 

 

消息订阅-发布机制 实现组件之间的通信

下载库PubSubsJS

npm install pubsub-js --save

使用

/*
1) import PubSub from 'pubsub-js';
2) token=PubSub.subscribe("delete",function(data){});//订阅 在收到消息的组件中的componentDidmount(){使用}
    //用法
     componentDidMount() {
        this.token = PubSub.subscribe('msg', (_, data) => {
            //接收到的信息
            console.log(data)
            this.setState({
                List: data
            })
        })
    }
3) PubSub.publish("msg",data);//发布 在发布消息的组件中使用

4) PubSub.unsubscribe(token);//卸载 在收到消息的组件中的componentWillUnmount(){使用}
   //用法:组件卸载时
    componentWillUnmount() {
        //卸载订阅消息
        PubSub.unsubscribe(this.token)
    }
*/
View Code

 

 

 路由 

  1 什么叫路由  

    1.       一个路由就是一个 映射关系(key,value)
    2.       key为path路径,value可能是function或component

  2路由的分类

    1.       后端路由
      1. 理解:value是function,用来处理客户端提交的请求
      2. 注册路由 router.get(path,function(req,res)=>{})
      3. 工作过程: 当node接收到一个请求时,根据请求路径找到匹配的路由,调用路由种的函数来处理请求,返回相应数据
    2.       前端路由
      1.  浏览器路由,value是component,用于展示页面内容
      2. 注册路由:<Router path="/test" component={Test} >
      3. 工作过程:当浏览器的path变为test时,当前路由组件就会变为Test组件

 

react-router-dom  (react  web 路由库)

安装 yarn add react-router-dom --save

  1. react 的一个插件库
  2. 专门用来实现一个SPA应用
  3. 基本react的项目基本会用到此库

路由的基本使用

  1. 明确好界面中的导航区展示区
  2. 导航区的a标签改为Link标签: <Link to="/xxx">Demo</Link>
  3. 展示区写Route标签进行路径的匹配 : <Route path="/xxx"  element={<Demo />} />
  4. <App>最外侧包裹了一个<BrowserRouter><HashRouter>

react-router-dom 相关的API

内置组件

  • <BrowserRouter/>  整个路由 只能通过一个路由器管理
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import 'antd/dist/antd.min.css';
import reportWebVitals from './reportWebVitals';
// 引入全局路由器
import {BrowserRouter} from 'react-router-dom'

ReactDOM.render(
  <React.StrictMode>
    {/* 路由器全局只能有一个 BroswerRouter*/}
    <BrowserRouter>
    <App />
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
View Code
  • <HashRouter/>
  • <Router/>  注册路由
  • <Link/>
  • <NavLink/> 使用和Link 一样   只是点击时可以添加需要的类名
import "./App.css";
import Home from "./views/Home";
import About from "./views/About";
import { Routes, Route, Link, NavLink } from "react-router-dom";

function App() {
  return (
    <div className="App">
      <h1>hello world</h1>
      <hr></hr>
      {/* 原生a标签跳转  React通过link标签(to 后面不识别大小写  建议小写) */}
      <Link to="/about" className="link">
        got to Aboout
      </Link>
      <hr></hr>
      <Link to="/" className="link">
        got to Home
      </Link>
      <hr></hr>
      {/* 点击NavLink时  会添上类名 在className中使用函数({isActive})=>isActive?'className':''*/}
      <NavLink
        to="/"
        className={({ isActive }) => (isActive ? "link clickActive" : "link")}
      >
        got to Home
      </NavLink>
      <hr></hr>
      <NavLink
        to="/about"
        className={({ isActive }) => (isActive ? "link  clickActive" : "link")}
      >
        got to Aboout
      </NavLink>
      {/* routes 表现 内部嵌套 具体的route路由页面 */}{" "}
      <Routes>
        <Route path="/" element={<Home />}></Route>{" "}
        <Route path="/about" element={<About />}></Route>{" "}
      </Routes>
    </div>
  );
}

export default App;
View Code

自己利用NavLink封装的MyNavLink组件  避免多写样式之类的内容

//封装组件
import React, { Component } from 'react'
import  {NavLink} from 'react-router-dom'

export default class MyNavLink extends Component {
    render() {
        console.log(this)
        return (
            <div>
                <NavLink className={({isActive})=>isActive?"link clickActive":"link"} {...this.props} />
            </div>
        )
    }
}

// 使用组件
import MyNavLink from "./components/myNavLink";
<MyNavLink to="/about" >About</MyNavLink>
<MyNavLink to="/" >Home</MyNavLink>
View Code
  • <Switch/>  旧版本   新版本 修改成了<Routes /> 为了 提高匹配效率 匹配到了路由 就停止匹配 
    {/* 旧版本是<Switch/> 新版本是<Routes /> */}
      <Routes>
        {/* 注册路由 */}
          <Route path="/" element={<Home />}></Route>{" "}
          <Route path="/about" element={<About />}></Route>{" "}
          <Route path="/about" element={<About />}></Route>{" "}
      </Routes>
View Code
  • <Redirect/> 重定向  当 前面的Route 都匹配不到的时候 按<Redirect />的来

 

其他

  • history对象
  • match对象
  • withRouter函数

路由组件与一般组件

react中解决多级路径刷新页面样式丢失问题(即用绝对路径 或者将BroswerRouter换成HashRouter)

 

路由的模糊匹配与严格匹配

   <MyNavLink to="/about/a/b">About</MyNavLink>
      <MyNavLink to="/">Home</MyNavLink>
      {/* routes 表现 内部嵌套 具体的route路由页面 */}{" "}
      {/* 旧版本是<Switch/> 新版本是<Routes /> */}
      <Routes>
        {/* 注册路由 */}
          <Route path="/" element={<Home />}></Route>{" "}
          {/* exact 默认模糊匹配  exact={true}精准匹配  必须path与Link或NavLink 的to属性值一致才会匹配到*/}
          <Route exact={true} path="/about" element={<About />}></Route>{" "}
      </Routes>
View Code

 

 自定义路由规则文件router.js

//改文件专门用于同一路由管理
import Login from '../pages/Login'
import User from '../pages/User'
import Home from '../pages/Home/'

//routes 数组中存储者所有的路由配置,每个路由配置都是一个对象

const routes = [
    {
        path: '/login',
        element: < Login / >
    },
    {
        path: '/user',
        element: < User / >
    },
    {
        path: '/',
        element: < Home / >
    },
]
export default routes;
View Code

使用 

import "./App.css";
import { Routes, Route } from "react-router-dom";
import routes from "./config/router";
function App() {
  return (
    <div className="App">
      <Routes>
        {routes.map((item) => {
          // 全写
          //  return <Route path={item.path} element={item.element} key={item.path}></Route>
          // 简写 批量传递
          return <Route {...item} key={item.path}></Route>;
        })}
      </Routes>{" "}
    </div>
  );
}

export default App;
View Code

 

 

 

 

 

深入了解setState

 

 

 

 

 

 

lazyLoad 懒加载

路由组件的lazyLoad

 HooKs

 

 

 

 

Context

 

 

 

 

 

 

posted @ 2021-05-07 19:59  还有什么值得拥有  阅读(75)  评论(0编辑  收藏  举报