React学习路线

目录

一、核心概念

二、状态管理

三、路由管理

子路由实现

实现admin组件在home组件中展示路由切换只在home页面完成

1.登陆成功页面跳转路由实现

四、实战React+antd


一、核心概念

中文官网:开始 – React

二、状态管理

Redux中文官网: 自述 · Redux

实例一、简易的按钮增加和减少 

changeState.js

let state = {
  count: 0,
};

const changeState = (action) => {
  action = action || { type: "" };
  switch (action.type) {
    case "increment":
      return {
        ...state,
        count: state.count++,
      };
    case "decrement":
      return {
        ...state,
        count: state.count++,
      };
    default:
      return state
  }
};

export { changeState };

store1.js

import { changeState } from "./changeState";

let state =  {}
const createStore = () => {
  // 获取状态
  const getState = () => {
    return state;
  };
  //观察者模式
  const listeners = [];
  const subscribe = (listener) => listeners.push(listener);

  const dispatch = (action) => {
    state = changeState()
    changeState(action);
    //publish
    listeners.forEach((listener) => listener());
    render();
  };

  return {
    dispatch,
    getState,
    subscribe,
  };
};
const store = createStore();

const render = () => {
  document.getElementById("count").innerHTML = store.getState().count
};
store.subscribe(render);

export default store;

App.jsx

import React from "react";
import store from "./store1";
class App extends React.Component{
    render(){
        return(
            <div>
                <button onClick={store.dispatch.bind(this,{type:'decrement'})}>-</button>
                <span id="count"></span>
                <button onClick={store.dispatch.bind(this,{type:'increment'})}>+</button>
             </div>
        )
    }
    componentDidMount(){
      store.dispatch()
    }
}

export default App

三、路由管理

React-react-router 搭配 React Router · Redux

入口文件index.js

import ReactDOM from 'react-dom/client';

import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <App></App>
);
 

App.jsx

import {BrowserRouter,Route,Routes} from 'react-router-dom'
import React from 'react'
import Home from './views/home'
import Login from './views/login'
class App extends React.Component{
    render(){
        return(
            <BrowserRouter>
                <Routes>
                    <Route path='/' element={<Login/>}></Route>
                    <Route path='/home/*' element={<Home/>}></Route>
                </Routes>
            </BrowserRouter>
        )
    }
}

export default App

login.jsx

import React from "react";


class Login extends React.Component{
    render(){
        return(
            <div>
                Login页面
            </div>
        )
    }
}

export default Login

子路由实现

实现admin组件在home组件中展示路由切换只在home页面完成

home.jsx

import React from "react";
import { Route, Link, Routes } from "react-router-dom";
import Admin from "./admin/admininfo";
class Home extends React.Component {
  render() {
    return (
      <div>
        Home页面
        <li>
          <Link to="/home/admin">admininfo</Link>
        </li>
        <div>
          <Routes>
            <Route path="/admin" element={<Admin />}></Route>
          </Routes>
        </div>
      </div>
    );
  }
}

export default Home;

1.登陆成功页面跳转路由实现

import { Navigate } from "react-router";
impost axios from 'axios'
class Login extends React.Component {
  state = {
    loginflag: false,
          };
   login = ()=>{
      axios.post(url,params).then(res=>{
            if(res){
                this.setState({
                    longiflag:true
                    })
                    }
             })}
   render() {
//当登录成功时表达式被执行页面跳转
    if(this.state.loginflag){
      return <Navigate to="/home" />
    }
    return (
            <div>
                <button onClick={this.login}>登录</button>
            </div>
        )

}

四、实战React+antd

react-yeb

 问题一、登录成功页面跳转

解决:定义一个state:loginflag:false

用 Navigate组件在render函数里

 if(this.state.loginflag){
      return <Navigate to="/home" />
    }

请求成功把loginflag改为true

import React from "react";
import { Button, Input } from "antd";
import "../css/login.css";
import { Navigate } from "react-router";
import { postRequset } from "../store/api";
class Login extends React.Component {
  state = {
    captchaimage: "/api/captcha?time=" + new Date(),
    username: "",
    password: "",
    code: "",
    loginflag: false,
  };
  componentDidMount() {}
  login =  () => {
    let data = {
      username: this.state.username,
      password: this.state.password,
      code: this.state.code,
      loginflag:false
    };
    postRequset("/api/login", data).then((res) => {
      if (res) {
        const tokenStr =res.obj.tokenHead+res.obj.token
        window.sessionStorage.setItem('tokenStr',tokenStr)
          this.setState({
            loginflag:true
          })
      }
    });
  };
  urlUpdate = () => {
    this.setState({
      captchaimage: "/api/captcha?time=" + new Date(),
    });
  };
  render() {
    if(this.state.loginflag){
      return <Navigate to="/home" />
    }
    return (
      <div id="login">
        <div className="loginarea">
          <div
            style={{
              position: "relative",
              top: "10%",
              fontSize: "30px",
              letterSpacing: "15px",
              left: "29%",
              fontWeight: "bolder",
              color: "#505458",
            }}
          >
            欢迎登陆
          </div>
          <div style={{ position: "relative", top: "20%", left: "10%" }}>
            <span>账号:</span>
            <Input
              size="large"
              style={{ width: "300px", marginLeft: "10px" }}
              onChange={(e) => this.setState({ username: e.target.value })}
            ></Input>
          </div>
          <div style={{ position: "relative", top: "22%", left: "10%" }}>
            <span>密码:</span>
            <Input
              size="large"
              onChange={(e) => this.setState({ password: e.target.value })}
              style={{ width: "300px", marginLeft: "10px" }}
            ></Input>
          </div>
          <div style={{ position: "relative", top: "26%", left: "10%" }}>
            <span style={{ position: "relative", right: "3%", bottom: "17px" }}>
              验证码:
            </span>
            <Input
              size="large"
              onChange={(e) => this.setState({ code: e.target.value })}
              placeholder="请输入验证码"
              style={{
                width: "120px",
                position: "relative",
                bottom: "17px",
                height: "37px",
                borderRadius: "0",
                marginLeft: "-5px",
                marginRight: "2px",
              }}
            ></Input>
            <img
              onClick={this.urlUpdate}
              src={this.state.captchaimage}
              width={95}
              style={{
                position: "relative",
                marginLeft: "0.5px",
                bottom: "5px",
              }}
            ></img>
          </div>
          <div style={{ position: "relative", top: "26%", left: "10%" }}>
            <Button
              size="large"
              type="primary"
              onClick={this.login}
              style={{ width: 100, margin: "10px", left: "8%" }}
            >
              登录
            </Button>
            <Button
              size="large"
              style={{ width: 100, margin: "10px", left: "15%" }}
            >
              退出
            </Button>
          </div>
        </div>
      </div>
    );
  }
}

export default Login;

问题二、点击子菜单路由跳转

解决:使用链式链接导航

import React from "react";
import { getRequest } from "../store/api";
import { Menu } from "antd";
import "../../node_modules/font-awesome/css/font-awesome.min.css";
import { Routes, Route, Navigate, Link } from "react-router-dom";
import EmpBasic from "./emp/EmpBasic";
import PerEc from "./per/PerEC";
import PerEmp from "./per/PerEmp";
import PerMv from "./per/PerMv";
import PerSalary from "./per/PerSalary";
import PerTrain from "./per/PerTrain";

import SalMonth from "./sal/SalMonth";
import SalSearch from "./sal/SalSearch";
import SalSob from "./sal/SalSob";
import SalSobCfg from "./sal/SalSobCfg";
import SalTable from "./sal/SalTable";

import StaAll from "./sta/StaAll";
import StaPers from "./sta/StaPers";
import StaRecord from "./sta/StaRecord";
import StaScore from "./sta/StaScore";

import SysAdmin from "./sys/SysAdmin";
import SysBasic from "./sys/SysBasic";
import SysCfg from "./sys/SysCfg";
import SysData from "./sys/SysData";
import SysInit from "./sys/SysInit";
import SysLog from "./sys/SysLog";

function getItem(label, key, icon, children, type) {
  return {
    key,
    icon,
    children,
    label,
    type,
  };
}

class Home extends React.Component {
  state = {
    routes: "/home/per/emp",
    item: [],
    keys: [],
    openKeys: ["2"],
    flag: false,
  };
  //实现只保留一个菜单
  onOpenChange = (key1) => {
    const latestOpenKey = key1.find(
      (key) => this.state.openKeys.indexOf(key) === -1
    );
    if (this.state.keys.indexOf(latestOpenKey) === -1) {
      this.setState({
        openKeys: [key1],
      });
    } else {
      this.setState({ openKeys: latestOpenKey ? [latestOpenKey] : [] });
    }
  };
  componentDidMount() {
    getRequest("/api/system/cfg/menu").then((res) => {
      let list = [];
      let opkeys = [];
      if (res) {
        res.forEach((item) => {
          opkeys.push(item.id + "");
          //子菜单列表 使用Link组件进行跳转
          let childrenlist = [];
          if (item.children) {
            item.children.forEach((children) => {
              childrenlist.push(
                getItem(
                  children.name,
                  "/home" + children.path,
                  <Link to={"/home" + children.path}></Link>,
                  null
                )
              );
            });
          }
          list.push(
            getItem(
              item.name,
              item.id,
              <i className={item.iconCls} style={{ color: "#1accff" }}></i>,
              childrenlist
            )
          );
        });
        this.setState({
          item: list,
          keys: opkeys,
        });
      }
    });
  }

  render() {
    return (
      <div>
        <div
          style={{ width: "100%", height: "88px", backgroundColor: "#5fa5f3" }}
        >
          <div style={{width:'20%',lineHeight:'80px',color:'white',fontWeight:'lighter',fontSize:'70px',fontFamily:"楷体",letterSpacing:'10px'}}>云e办</div>
        </div>
        <Menu
          openKeys={this.state.openKeys}
          onOpenChange={this.onOpenChange}
          mode="inline"
          multiple={false}
          style={{ width: "12%" }}
          items={this.state.item}
        ></Menu>
        <div
          style={{
            width: "88%",
            height: "87.6%",
            position: "absolute",
            left: "12%",
            bottom: "0",
          }}
        >
          <Routes>
            <Route path="/emp/basic" element={<EmpBasic />}></Route>
            <Route path="/per/emp" element={<PerEmp />}></Route>
            <Route path="/per/ec" element={<PerEc />}></Route>
            <Route path="/per/train" element={<PerTrain />}></Route>
            <Route path="/per/salary" element={<PerSalary />}></Route>
            <Route path="/per/mv" element={<PerMv />}></Route>
            <Route path="/sal/sob" element={<SalSob />}></Route>
            <Route path="/sal/sobcfg" element={<SalSobCfg />}></Route>
            <Route path="/sal/table" element={<SalTable />}></Route>
            <Route path="/sal/month" element={<SalMonth />}></Route>
            <Route path="/sal/search" element={<SalSearch />}></Route>
            <Route path="/sta/all" element={<StaAll />}></Route>
            <Route path="/sta/score" element={<StaScore />}></Route>
            <Route path="/sta/pers" element={<StaPers />}></Route>
            <Route path="/sta/record" element={<StaRecord />}></Route>
            <Route path="/sys/basic" element={<SysBasic />}></Route>
            <Route path="/sys/cfg" element={<SysCfg />}></Route>
            <Route path="/sys/log" element={<SysLog />}></Route>
            <Route path="/sys/admin" element={<SysAdmin />}></Route>
            <Route path="/sys/data" element={<SysData />}></Route>
            <Route path="/sys/init" element={<SysInit />}></Route>
          </Routes>
        </div>
      </div>
    );
  }
}

export default Home;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值