React+TS学习和使用(三):React Redux和项目的路由配置

开启学习react+ts,本篇主要是学习使用React Redux和项目的路由配置

一、React Redux

需求:使用TS+React Redux实现一个累加。

A. 安装

$ yarn add redux react-redux redux-devtools-extension

B. Store

src下新建 store 目录,在其中新建 reducer.tsindex.ts

a. reducer
const defaultState = {
    num: 1
}

interface IAction {
    type: string;
    value: number;
}

// eslint-disable-next-line
export default (state=defaultState, action: IAction) => {
    let newState = JSON.parse(JSON.stringify(state));
    switch(action.type){
        case "increase":
            newState.num+=action.value;
            break;
        default:
            break;
    }
    return newState;
}
    
b. store
import {applyMiddleware, createStore} from 'redux'
import reducer from './reducer'
import {composeWithDevTools} from 'redux-devtools-extension'

const store = createStore(reducer, composeWithDevTools(applyMiddleware()))
export default store;
    

C. Provider

在入口文件 index.tsx 中:

import ReactDOM from 'react-dom'
import App from './App4'
import {Provider} from 'react-redux'
import store from 'store'

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById("root")
)

D. connect

在组件中:

import {connect} from 'react-redux'
import React from 'react'
import {Dispatch} from 'redux'	// redux提供了Dispatch作为dispatch的类型检测接口

interface IProps {
    num: number;
    increaseFn: ()=>void
}

const App4: React.FC<IProps> = (props) => {
    return (
        <div>
            <h3>{props.num}</h3>
            <button onClick={()=>props.increaseFn()}>累加</button>
        </div>
    )
}

const mapStateToProps = (state: {num: number}) => {
    return {
        num: state.num
    }
}

const mapDispatchToProps = (dispatch: Dispatch) => {
    return {
        increaseFn(){
            dispatch({type: "increase", value: 2})
        }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(App4)

五、路由

1、安装路由

本课程使用目前最新版的React路由(v6) (opens new window)

$ npm install react-router-dom@6
# 或者
$ yarn add react-router-dom@6

注意:

版本会随时更新,因此请指定版本安装。

2、路由配置

a. 路由创建

src 下创建 router>index.tsx。以首页与登录页切换为例:

import App from "App6";
import Home from "Home";
import List from "List";
import Detail from "Detail";
import About from "About";
import Login from "Login";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";

const MyRouter = () => (
  <Router>
    <Routes>
      <Route path="/" element={<App />}>
        <Route index element={<Home />}></Route>
        <Route path="/list" element={<List />}></Route>
        <Route path="/detail" element={<Detail />}></Route>
        <Route path="/about" element={<About />}></Route>
      </Route>
      <Route path="/login" element={<Login />}></Route>
    </Routes>
  </Router>
);

export default MyRouter;
    

关键词解析:

1、BrowserRouter重命名为Router

2、所有的Route组件必须放在Routes组件中

3、Route标签上的element属性必须填写标签结构的组件,如:,而不是 Home

4、加了index属性的路由不需要写path,因为/路径就指向该组件

b. 入口文件引入路由

src>index.tsx

import ReactDOM from 'react-dom'
import MyRouter from 'router'

ReactDOM.render(
    <MyRouter />,
    document.getElementById("root")
)
    
c. 组件显示

App.tsx 中:

import React from "react";
import { Outlet, Link } from "react-router-dom";

function App() {
  return (
    <div>
      <ul>
        <li><Link to={"/list"}>列表页</Link></li>
        <li><Link to={"/detail"}>详情页</Link></li>
        <li><Link to={"/about"}>关于我们</Link></li>
      </ul>
      <Outlet />
    </div>
  );
}

export default App;
    

关键词解析:

1、 组件用来显示子路由,类似于Vue的

2、Link最终会被html解析为a标签

目前结合ts的情况下,无法使用index属性指定首页组件,因此如果希望 / 跳转 /home,需要:

import { useLocation } from "react-router-dom";

let { pathname } = useLocation();
useEffect(() => {
    if (pathname === "/") {
        navigate("/home");
    }
}, []);
    

3、参数获取

a. 子路由形式携带

路由跳转往往伴随着参数的传递,假如:

// 登录页的路由配置
<Route path="/login/:id" element={<Login />}></Route>

// Link跳转路由
<Link to="/login/123">登录页</Link>
    

此时可以使用React Router Dom提供的Hook来获取:

import { useParams } from 'react-router-dom'

// 从路由参数中解构出来
const {id} = useParams()
console.log(id)    // 123

b. 问号(?)形式参数
// 登录页的路由配置
<Route path="/login" element={<Login />}></Route>

// Link跳转路由
<Link to="/login?id=123">登录页</Link>

获取形式:

import { useSearchParams } from 'react-router-dom'

const [params] = useSearchParams()
console.log(params.getAll('id'))    // ['123']
  

以上的id其实属于携带方式不明确,也不一定会携带,因此路由可以设置为:

<Route path="/login/*" element={<Login />}></Route>

4、事件跳转

事件中执行跳转页面,可以使用useNavigate这个hook进行跳转。

import { useNavigate } from "react-router-dom";

const navigate = useNavigate();
const goLogin = () => {
    navigate('/login')
}

<span onClick={goLogin}>登录页2</span>
    

简单参数的传递可以直接带在url后,而复杂参数需要以复杂数据类型的形式携带:

const navigate = useNavigate();
navigate('/login', {state: {id: 456}})
    

注意:

navigate方法第二个参数必须是对象,而且这个对象只接受replace和state两个属性,state可以用来携带参数。

携带复杂参数,可以使用useLocation来获取参数:

const location = useLocation()
console.log(location.state.id);  // 456
  

注意:

这里如果使用了TS,那么location会报错,因为其中的state属于不确定的类型,因此没办法直接location.state调用。解决方法有两个:一是单独设置state字段为any,二是直接设置location类型为any。

// 方法一:设置state为any
interface ILocation {
    state: any,
    search: string,
    pathname: string,
    key: string,
    hash: string
}

const location: ILocation = useLocation()

// 方法二:设置location为any
const location: any = useLocation()
 

5、404匹配

当路由为404时,可以对路由文件 router/index.tsx 进行如下匹配:

...
import NoMatch from "NoMatch";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";

const MyRouter = () => (
  <Router>
    <Routes>
      <Route path="/" element={<App />}>
        ...
      </Route>
      <Route path="/login" element={<Login />}></Route>
      <Route path="*" element={<NoMatch />}></Route>
    </Routes>
  </Router>
);

export default MyRouter;
    

如此,输入错误路径,就会自动重定向到404页面了。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
作为前端使用React、TypeScript、React Router、Redux、Axios、Ant Design和Sass开发ERP软件项目的职责描述,主要包括以下几个方面: 1. 分析需求和设计界面:与产品经理、设计师等团队成员合作,分析用户需求和产品设计,设计符合用户需求的界面,并提供良好的用户体验。 2. 使用React和TypeScript开发组件:根据设计稿或需求文档,使用React和TypeScript开发可复用的组件,利用类型检查提高代码的可靠性和可维护性。 3. 使用React Router实现路由管理:使用React Router进行页面之间的导航和路由管理,确保页面之间的跳转和参数传递的正常。 4. 使用Redux进行状态管理:使用Redux进行全局状态的管理,包括定义和处理数据流、异步操作、状态持久化等,确保数据的一致性和可控性。 5. 使用Axios进行网络请求:使用Axios库发送HTTP请求与后端API进行数据交互,并处理请求的错误和异常情况。 6. 使用Ant Design进行UI开发:使用Ant Design提供的组件库进行界面开发,保证界面的一致性和美观性,并根据需求进行自定义样式。 7. 使用Sass进行样式管理:使用Sass预处理器编写可复用的样式代码,提高样式开发效率,并保持样式的可维护性。 8. 优化性能和用户体验:通过前端优化技术(如代码分割、懒加载、缓存等),提升ERP软件的性能和用户体验,确保页面加载速度快、操作流畅。 9. 跨浏览器兼容性测试:测试并确保ERP软件在各种主流浏览器(如Chrome、Firefox、Safari等)下的正常运行,并解决兼容性问题。 10. 代码版本管理和团队协作:使用版本管理工具(如Git)管理代码,与团队成员协作开发,参与代码评审和项目迭代。 11. 系统维护和故障排除:及时响应用户反馈并解决软件中出现的前端问题,修复bug,确保ERP软件的稳定运行。 总的来说,前端使用React、TypeScript、React Router、Redux、Axios、Ant Design和Sass开发ERP软件项目的职责是负责开发和维护ERP软件的前端界面和功能,与后端进行数据交互,优化性能和用户体验,并与团队成员协作推动项目的成功交付。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨小凹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值