关于react-router:React18TS-通用后台管理系统解决方案落地实战

download:React18+TS 通用后盾管理系统解决方案落地实战React 18+TS的基本概念TypeScriptTypeScript是一种动态类型的编程语言,它可能在编译时查看代码中的类型谬误,从而提高代码的可读性和可维护性1。TypeScript还支持ES6+的新个性,如类,模块,箭头函数,解构赋值等,使得代码更加简洁和现代化1。 TypeScript可能与React框架无缝集成,只需要安装相应的类型定义文件即可。例如,要使用React 18+TS开发利用,可能执行以下命令: npm install --save react@next react-dom@nextnpm install --save-dev typescript @types/react @types/react-dom这样就可能在.ts或.tsx文件中使用React和TypeScript了。 React 18React 18是React框架的最新版本,它蕴含了一些重大的更新和改进2。其中最引人瞩目的是Server Components,它可能让开发者在服务器端渲染组件,并将后果发送给客户端3。这样可能缩小客户端的代码量和网络传输量,提高利用的加载速度和响应速度3。 另一个重要的个性是Suspense,它可能让开发者在组件中申明数据依赖,并在数据加载时浮现一个占位符4。这样可能避免组件在渲染过程中出现闪动或空白的情况,提高用户体验4。 还有一个值得关注的个性是Concurrent Rendering,它可能让React在后盾渲染更新,并在合适的时机浮现给用户5。这样可能避免长时间的渲染工作阻塞用户交互,提高利用的流畅度和稳定性5。 要使用React 18+TS开发利用,需要配置一些实验性的个性。例如,在tsconfig.json文件中增加以下内容: { "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "react", "experimentalDecorators": true, "useDefineForClassFields": true }}这样就可能在.tsx文件中使用JSX语法,并启用装璜器和类字段等个性了。 React 18+TS的劣势使用React 18+TS开发前端利用有以下几个劣势: 可能利用TypeScript的类型零碎和ES6+的新个性,编写更加健壮、简洁和现代化的代码。可能利用React 18的新个性,如Server Components, Suspense, Concurrent Rendering等,提高利用的性能和用户体验。可能享受React生态系统中丰富的资源和工具,如 Create React App, Next.js, React Router, Redux, Material UI等,疾速搭建和部署利用。 React 18+TS在线教育平台示例为了展示如何使用React 18+TS构建一个在线教育平台,简略实现一个前端页面,浮现课程列表和课程详情。 首先,咱们需要创建一个React 18+TS我的项目,可能使用Create React App工具,执行以下命令: npx create-react-app react18-ts-edu --template typescriptcd react18-ts-edunpm start这样就可能在阅读器中看到一个默认的页面了。 接下来,咱们需要安装一些依赖库,如GraphQL, Apollo Client, Material UI等,执行以下命令: ...

August 19, 2023 · 2 min · jiezi

关于react-router:Reactrouter-V6-拦截-路由跳转

指标实现成果:拦挡路由变动做自定义解决,比方在一个表单尚未填写实现,用户就要来到以后页面此时须要给用户做一个揭示,如下图所示 先说一下背景常识:React-router 是由三个库一起组成的 history、react-router、react-router-dom 咱们平时须要用到的是 react-router-dom v5 版本实现路由拦挡以前在应用 v5 版本时,是这样实现路由拦挡的 // 文档:https://v5.reactrouter.com/core/api/Prompt <Prompt when={boolean} // 组件何时激活 message={(location, action) => { // 做一些拦挡操作 location 要返回的路由,此时能够先保留下来后续应用 // return false 勾销跳转 比方此时弹起一个自定义弹窗, // return true 容许跳转 }} />v6 版本实现v6 版本没有了 Prompt 组件,Google 搜寻之后找到了这个 stackoverflow v6 beta 时提供了两个 hooks useBlocker/usePrompt 能够用来实现路由拦挡,然而到正式版的时候这两个 hook 就被移除了,这个 issue 外面有探讨,这里有人找出了解决方案就是把删除的这两个 hooks 再加回去 其实路由拦挡性能次要是用到了 history 库外面的 block 办法,这里是相干代码histoy block 文档 history.block will call your callback for all in-page navigation attempts, but for navigation that reloads the page (e.g. the refresh button or a link that doesn't use history.push) it registers a beforeunload handler to prevent the navigation. In modern browsers you are not able to customize this dialog. Instead, you'll see something like this (Chrome):简略的翻译下就是 histoy.block 会阻止页面中的所有导航并调用callback,然而间接敞开 tab 页或是刷新会注册 beforeunload 事件继而触发浏览器的默认询问弹窗,不反对去除默认弹框,我上面采纳了一种 hack 的方法来去除 默认询问弹框残缺代码 ...

August 11, 2022 · 2 min · jiezi

关于react-router:react使用BrowserRouter部署到docker的httpd刷新页面报错Not-Found404解决方案

找到httpd.conf配置文件(/usr/local/apache2/conf)进入编辑找到#LoadModule rewrite_module modules/mod_rewrite.so这一行并勾销正文找到所有的AllowOverride,将默认值none批改为All(大概有三处,不要漏)在我的项目根目录(/usr/local/apache2/htdocs)新建.htaccess文件,输出以下内容:<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L]</IfModule>保留后退出。 重启http容器

July 22, 2022 · 1 min · jiezi

关于react-router:从-React-Router-v5-过渡到-v6

React-router 是 react js 中路由的规范库。它容许 React 应用程序的用户在应用程序的不同局部(组件)之间挪动。 react-router 团队 发表将 在 2021 年底公布react-router 版本 6 (v6) 的稳固版本,但因为一些重大的 API 更改,从 react-router 版本 5 (v5) 切换到 v6 可能会很艰难. 在本文中,咱们将介绍 v6 中的新性能以及如何将现有的 React 我的项目从 v5 降级到 v6。 要在咱们的应用程序中降级 react-router 包的版本,咱们导航到我的项目文件夹并运行 npm install react-router-dom@[VERSION_NUMBER]替换VERSION_NUMBER为咱们要装置的版本,或者如果咱们想要最新版本,则替换为“ latest ”,如下所示: npm install react-router-dom@6或者 npm install react-router-dom@latest请留神,咱们必须连贯到互联网能力实现装置,否则装置将失败。另外,请确保我的项目中的 react 版本是 v16.8 或更高版本,因为 react-router v6 重大依赖于 react v16.8 最后反对的钩子 Switch 被替换为 Routesv5 时代的第一个被代替的是Switch组件。该Switch组件用于包装咱们的路由,它确保每次只加载一个匹配的路由。但这在 v6 中不再存在。咱们应用Routes组件来替换Switch。请留神,咱们依然须要导入BrowserRouter包装咱们的应用程序,就像在 v5 中所做的那样。 在 v5 中,咱们是这样做: ...

January 14, 2022 · 3 min · jiezi

关于react-router:react嵌套路由多重路由重定向重定向到404页面

在react 中,路由重定向的外围就是Redirect和Switch ,不论是单层路由还是多层 import { HashRouter,BrowserRouter, Route,Router, Link, Redirect, Switch} from "react-router-dom";import Header from './components/Header';import Login from './page/Login/index';import Register from './page/Login/register';import RemakePassWord from './page/Login/remakePassWord';import HomeIndex from './page/Login/HomeIndex';import List from './page/Login/List';import Error from './page/Login/Error';const App=() =>{ return ( <div className="App"> <BrowserRouter>{/* 哈希router还是Browser随需要*/} <Header/> <Switch> {/* 想要重定向匹配精确 Switch必须加 Switch只显示匹配到的第一个路由*/} <Route exact path="/" component={Login} /> <Route path="/register" component={Register} /> <Route path="/remakePassWord" component={RemakePassWord} /> {/* 一层路由重定向 重定向到Login */} <Redirect to="/" /> {/*二层路由*/} <Route path="/main" > <Switch>{/*二层想要重定向精确 二层Switch也是必须加的 */} <Route path="/main/homeIndex" component={HomeIndex} /> <Route path="/main/list" component={List} /> <Route path="/main/404" component={Error} /> {/* 二层路由重定向 重定向到Error页面 写/main/404和404都行 */} <Redirect to="/main/404" /> </Switch> </Route> </Switch> </BrowserRouter> </div> );}...export default App;

May 9, 2021 · 1 min · jiezi

单页面路由切换原理简单实现

前言最近学习react时,在使用react-router-dom的时候,对history原理与路由切换实现并不了解,经过学习后总结一下吧!如果你只是使用react 自带history 那下面这些原理,你可能并不会用到。但当需要使用自己的history 或 使用第三方history 的时候你就需要了解其原理在react 中,你要在非组件内可以灵活的切换路由,那么你就要使用自定义的history。 // app.jsximport React from 'react'import './App.scss'import { BrowserRouter } from 'react-router-dom'import history from './history'import XtContent from './layout/content'import Login from './components/loginModal'function App() { return ( <div className="App"> <BrowserRouter history={history} basename="/xiutui"> <Login /> <XtContent /> </BrowserRouter> </div> )}export default App // history.js // 这里使用第三方创建history import { createBrowserHistory } from 'history'export default createBrowserHistory()// 在封装的fetch中使用import axios from 'axios'import history from '@/history';// 设置axios 通用const service = axios.create({ timeout: 5000, headers: { 'Content-Type': 'application/json;charset=UTF-8' }, withCredentials: true})// 响应拦截service.interceptors.response.use( response => { //服务端定义的响应code码为0时请求成功 if (response.data.code === 200) { //使用Promise.resolve 正常响应 return Promise.resolve(response.data) } else if (response.data.code === 1002) { //服务端定义的响应code码为1401时为未登录 message.error('登陆失效,请从新登陆!') /////////// 登陆失败切换登陆页面 **history.push('/Login')** ////////// window.localStorage.removeItem('userInfo') return Promise.reject(response.data) //使用Promise.reject 抛出错误和异常 } else { message.error(response.data.message) return Promise.reject(response.data) } }, error => { if (error && error.response) { let res = {} res.code = error.response.status res.msg = throwErr(error.response.status, error.response) //throwErr 捕捉服务端的http状态码 定义在utils工具类的方法 message.error(res.msg) return Promise.reject(res) } return Promise.reject(error) })模式在React/Vue的路由时,会有两种模式 hash 和 history ,事实上他们是针对游览器的路由模式设置的。其基本原理实际就是通关游览器提供的监听这两种模式的变化,从而映射的对应路由的组件render. ...

August 7, 2019 · 3 min · jiezi

reactrouter-v5x-源码分析和理解-SPA-router-的原理

这篇文章主要讲的是分析 react-router 源码,版本是 v5.x,以及 SPA 路由实现的原理。 文章首发地址单页面应用都用到了路由 router,目前来看实现路由有两种方法 hash 路由和 H5 History API 实现。 而 react-router 路由,则是用到了 history 库,该库其实是对 hash 路由、history 路由、memory 路由(客户端)进行了封装。 下面先看看 hash 和 history 是怎样实现路由的。 hash routerhash 是 location 的属性,在 URL 中是 #后面的部分。如果没有#,则返回空字符串。 hash 路由主要实现原理是:hash 改变时,页面不发生跳转,即 window 对象可以对 hash 改变进行监听(hashchange 事件),只要 url 中 hash 发生改变,就会触发回调。 利用这个特性,下面模拟实现一个 hash 路由。 实现步骤: 初始化一个类记录路由、history 历史值添加 hashchange 事件,hash 发生改变时,触发回调初始添加所有路由模拟前进和回退功能代码如下: hash.html <html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>hash router</title></head><body> <ul> <li><a href="#/">turn yellow</a></li> <li><a href="#/blue">turn blue</a></li> <li><a href="#/green">turn green</a></li> </ul> <button id='back'>back</button> <button id='forward'>forward</button> <script src="./hash.js"></script></body></html>hash.js ...

July 10, 2019 · 9 min · jiezi

reactrouter-使用

本次使用react-router 版本为 5.0.1本教程前提是你的应用程序是一个web应用程序,使用’react-router-dom‘包来实现页面的路由在React router中有三种类型的组件,一是路由组件第二种是路径匹配组件第三种是导航组件。路由组件: BrowserRouter 和 HashRouter 路径匹配的组件: Route 和 Switch 导航组件: Link 安装npm install react-router-dom简单用法import React from 'react'import TodoList from './components/TodoList'import { BrowserRouter as Router, Route, Link } from 'react-router-dom'import './App.css'const App: React.FC = () => { return ( <div className='App'> <Router> <Link to='/'>root</Link> <br /> <Link to='/hello'>hello</Link> <br /> <Link to='/todolist'>todolist</Link> <div> <Route path='/' exact render={() => { return <div>root page</div> }} /> <Route path='/hello' render={() => { return <div>hello world</div> }} /> <Route path='/todolist' component={TodoList} /> </div> </Router> </div> )}export default App通过上面的代码我么就实现了我们项目的基本路由功能,Router组件决定了我们使用html5 history api,Route组件定义了路由的匹配规则和渲染内容,使用 Link 组件进行路由之间的导航。使用 exact 属性来定义路径是不是精确匹配。 ...

June 8, 2019 · 2 min · jiezi

reactrouter40-使用方法和源码分析

react-router-dom@4.3.0 || react-router@4.4.1react-router 使用方法配置 router.js import React, { Component } from 'react';import { Switch, Route } from 'react-router-dom';const router = [{ path: '/', exact: true, component:importPath({ loader: () => import(/* webpackChunkName:"home" */ "pages/home/index.js"), }), },]const Routers = () => ( <main> <Switch> { router.map(({component,path,exact},index)=>{ return <Route exact={exact} path={path} component={component} key={path} /> }) } </Switch> </main>);export default Routers;入口 index.js import {HashRouter} from 'react-router-dom';import React from 'react';import ReactDOM from 'react-dom';import Routers from './router';ReactDOM.render ( <HashRouter> <Routers /> </HashRouter>, document.getElementById ('App'));home.js ...

June 3, 2019 · 4 min · jiezi

react用子组件有RouteComponentProps报错match-is-missing-in-type

因为子组件有RouteComponentProps,所以在父组件中引用需要传相应的属性。但考虑到如果层级较深的话一层一层传就很麻烦。而如果我们用route组件引用的话就会很简单,只需要在需要子组件的地方用route的render属性就可以了: <Route render={(props) => <InputItem {...props} onChange={(value) => this.handleInputChange(value)} title={'手机号'} />

May 22, 2019 · 1 min · jiezi

reactrouter中的exact和strict

前言每次用配置react路由都会考虑是否应该给给<Route>组件加上exact或strict。下面妹子将于自认为比较清晰的方式列举出来什么场景需要加和不加。 本文案例主要以react-router v4+为主,v5版本是因为发布时版本依赖有问题而直接跳成这个大版本的,用法和4完全相同,就是这么任性 > < ,升级详情可看本文最后链接exactexact默认为false,如果为true时,需要和路由相同时才能匹配,但是如果有斜杠也是可以匹配上的。如果在父路由中加了exact,是不能匹配子路由的,建议在子路由中加exact,如下所示 //父路由<Switch> <Route path="/a" component={ComponentA} /></Switch>//子路由,tuanDetail组件里<Switch> <Route path="/a/b" exact component={ComponentB}/></Switch>strict<Route strict path="/one" component={About} /> strict默认为false,如果为true时,路由后面有斜杠而url中没有斜杠,是不匹配的 案例 总结如果没有子路由的情况,建议大家配都加一个exact;如果有子路由,建议在子路由中加exact,父路由不加;而strict是针对是否有斜杠的,一般可以忽略不配置。 其他链接原文地址:https://raoenhui.github.io/react/2019/05/04/exact-strict/https://reacttraining.com/react-router/web/api/Route/exact-boolhttps://reacttraining.com/blog/react-router-v5/Happy coding .. :)

May 10, 2019 · 1 min · jiezi

react离开页面自定义弹框拦截路由拦截

前言:项目有个需求是:跳转路由,在离开页面前,需要弹框询问用户是否确定离开。用react-router的<Prompt>组件是可以的,但是,怎么使用antd组件(或者说自定义组件)呢?请看下面 先看的这个:https://stackoverflow.com/questions/32841757/detecting-user-leaving-page-with-react-router(1)使用react-router的<Prompt> import { Prompt } from 'react-router'<Prompt message="你确定要离开嘛?"/> (2)<Prompt>支持函数 <Prompt when={true} message={(location) => { return window.confirm(`confirm to leave to ${location.pathname}?`); }}/> (3)history.block,这个是个坑! import { history } from 'path/to/history';class MyComponent extends React.Component { componentDidMount() { history.block(targetLocation => { // take your action here return false; }); } render() { //component render here }}坑的原因是history.block()方法是不能和<Modal>组件并列使用的,而必须在history.block()内部去调用<Modal>组件(就是注释take your action here那里),这就导致一个问题:<Modal>组件里的 onOk、onCancel 如何返回值给 history.block()的 return 语句(return false/true)的同时,不让history.block()的 return 语句和 <Modal>组件顺序执行呢? 说白点就是,<Modal>组件先显示出来,阻塞后面的 return false/true,等 <Modal>组件的 onOk、onCancel 方法执行后,再 return false/true ...

May 8, 2019 · 1 min · jiezi

React-Router-v4教程为你的-React-应用创建路由

翻译:疯狂的技术宅原文:https://www.edureka.co/blog/r...本文首发微信公众号:前端先锋欢迎关注,每天都给你推送新鲜的前端技术文章 在这篇关于 React Router 的博文中,我将引导你搞懂 React 中路由的概念。 你将看到以下主题: 常规路由为什么需要 React 路由?React 中的路由React Router v4 的优点常规路由通常,当用户在浏览器中键入 URL 时,会向服务器发送 HTTP 请求,然后服务器检索 HTML 页面。对于每个新URL,用户会被重定向到新的 HTML 页面。你可以通过参考下图来更好地理解路由的工作原理。 为什么需要 React 路由?将单页应用限制为单一视图并不适用于 Facebook、Instagram 等流行的社交媒体网站,这些网站现在使用 React 呈现多个视图。我们需要继续前进,学习如何在单页面应用中显示多个视图。 例如我们习惯看到显示欢迎消息和相关内容的主页。网站介绍的详细信息可以在“关于我们”页面上找到,用户列表及其详细信息会出现在不同的页面上,可能还有其他各种页面包含很多不同的视图。 那么你认为这是怎样实现的呢? 在程序中添加路由器可以解决这一需求。 React 中的路由这将把我们带到本文的主题:React Router v4。 2017年3月13日,Micheal Jackson 和 Ryan Florence 发布了React Router v4 及可靠的文档。 他们相信“Learn Once, Route Anywhere”的理念。 在 React Conf 2017 的演讲中,他们通过展示如何将路由概念无缝地从 Web 平台投射到 Native 平台,以及将 React Router 集成到 VR 并在 React Native 中创建动画来解释这一点。虽然他们的谈话中的着眼点是围绕路由器 API 是如何“All About Components”的。 ...

April 23, 2019 · 2 min · jiezi

从项目中由浅入深的学习react (2)

序列文章从项目中由浅入深的学习vue,微信小程序和快应用(1)前言从pc(dva+umi)和mobile(原生react)两个项目来介绍react的使用 搞懂这两个项目,上手撸react代码so-easy1.react-pc-template篇1.1效果图react-pc-template项目, 欢迎star1.2技术栈dva+umi+ant-design-prodva:可拔插的react应用框架,基于react和reduxmui:集成react的router和reduxant-design-pro:基于react和ant-pc的中后台解决方案1.3适配方案左侧固定宽度,右侧自适应右侧导航分别配置滚动条.控制整个page1.4技能点分析技能点对应api3种定义react组件方法1.函数式定义的无状态组件; 2.es5原生方式React.createClass定义的组件; 3.es6形式的extends React.Component定义的组件JSXreact是基于jSX语法react16之前生命周期实例化(6个):constructor,getDefaultProps,getInitialState,componentWillMount,render,componentDidMountreact16生命周期实例化(4个):constructor,getDerivedStateFromProps,componentWillMount,render,componentDidMount生命周期更新:5个生命周期生命周期销毁:componentWillUnmout路由基于umi,里面有push,replace,go等方法状态管理dva里面的redux的封装,属性有state,effects,reducers组件传值父子:props,平级redux或umi的routermodel项目的model和dom是通过@connect()连接并将部分属性添加到props里登陆登陆是通过在入口js里面做路由判断1.5那么问题来了?三种定义react组件方式的区别?解析umi的router传参形式? 解析dva封装的redux和原生的redux使用有那些不同? dva使用解析redux使用解析umi里面router实现原理?umi源码对比vue和react在原理和使用上的区别?2.react-mobile篇2.1 效果图react-mobile项目,欢迎star2.2 技术栈react + react-router-v4 + redux +ant-design-mobile+iconfontreact-router-v4:路由4.x版本redux:状态管理ant-design-mobile:UI组件iconfont:字体icon2.3 适配方案rem适配2.4技能点分析技能点对应的apireact-dom提供render方法react-router 4.x组成react-router(核心路由和函数) , react-router-dom(API) , react-router-native( React Native 应用使用的API)react-router 4.x的APIrouter(只能有一个) , route(匹配路由渲染UI) , history, link(跳转) , navlink(特定的link,会带样式) , switch(匹配第一个路由) , redirect(重定向) , withRouter(组件,可传入history,location,match 三个对象)react-router 3.x组成就是react-routerreact-router 3.x的APIrouter , route , history , indexRedirect(默认加载) , indexRedirect(默认重定向) , link(跳转) , 路由钩子(onEnter进入,onLeave离开)4.x已经去掉historyreact-router有三种模式:1.browserHistory(需要后台支持); 2.hashHistory(有’#’); 3.createMemoryHistoryredux单向数据流 , action(通过dispatch改变state值) , reducer(根据 action 更新 state) , store(联系action和reducer)react-redux1.连接react-router和redux,将组件分为两类:UI组件和容器组件(管理数据和逻辑) , 2.connect由UI组件生成容器组件 , 3.provider让容器组件拿到state ,4.mapStateToProps:外部state对象和UI组件的props映射关系,5.mapDispatchToProps:是connect第二个参数, UI 组件的参数到store.dispatch方法的映射react-loadable代码分割,相当于vue-router中的路由懒加载classNames动态css的类2.5 那么问题来了1.react-router 3.x和react-router 4.x的区别?react-router 3.x文档 react-router 4.x文档2.redux和react-redux的关系?react-redux和redux介绍3.react-router 4.x取消了路由钩子怎么做登陆授权判断?const PrivateRoute = ({ component: Component, …rest }) => ( <Route {…rest} render={props => ( fakeAuth.isAuthenticated ? ( <Component {…props}/> ) : ( <Redirect to={{ pathname: ‘/login’, state: { from: props.location } }}/> ) )}/>)利用路由的render属性来做拦截,判断是否授权,否则利用redirect重定向3.结语这个相当于react的入门篇,撸项目是完全可以但react生态超级繁荣,同一个功能插件版本不同,对应的api也不同,一些高级用法后续再更新 ...

April 3, 2019 · 1 min · jiezi

两行代码让你去创建react项目

最近自己在学习react,可以是create-react-app 创建的项目没有react-router,感觉不怎么好用(最要是为自己新建项目的时候偷懒吧),然后自己开发了个脚手架(react+react-router),直接上代码,不墨迹了1.npm install -g create-react-pro(此处我得自己吐槽一下自己,这个命名的问题,我发npm包的时候,发现create-react-frame和create-react-project这两个名字都被占用了,没想出什么好的名字,忘大家轻点吐槽)2.create-react-pro(输入这个命令直接去创建新的项目即可)如果项目中觉得有什么可以优化的地方,可以提出来,我可以去改进(自己一直在用vue,最近才开始转react,希望react大神提出点优化性的建议),谢谢各位大佬;

April 2, 2019 · 1 min · jiezi

React-Router V5 尝鲜

新特性完全兼容老版本v4支持 React 16 , 兼容 React >= 15消除在 React.StrictMode 严格模式中的警告使用 create-react-context 实现 context API新功能Route 组件 path 可以为数组before<Switch> <Route path="/users/:id" component={User} /> <Route path="/profile/:id" component={User} /></Switch>after<Route path={["/users/:id", “/profile/:id”]} component={User} />支持 React.createRef in <Link innerRef>举个栗子// 通过以下方式可以获取到 Link 组件对应的 DOM 元素this.createRef = React.createRef();<Link to="/home" innerRef={this.createRef}>home</Link>支持 React.forwardRef in <Route component>举个栗子<Route path="/home" component={Home}/>// Home 组件export default React.forwardRef((props, ref) => { // 纯函数组件也能获取到 ref (当前 Home 组件对应的 DOM 元素) console.log(props, ref); return <h2>Home</h2>})以上功能是 v4 没有的功能,而在 v5 新增的。 什么?还想知道更多内幕消息?关注这个博客吧 –> 博客传送门 ...

March 25, 2019 · 1 min · jiezi

React-Router 杂记

三种Router的区别1. HashRouter: 即对应url中的hash值,如xx.com/#/a、xx.com/#/a/b, 服务器对任务url都返回同一个url,具体的路径由浏览器区分,因为浏览器不会发送hash后面的值给服务器。 2. BrowserRouter:如果是BrowseRouter即url变成这样,xx.com/a、xx.com/a/b, 所以要对服务器配置不同的url返回不同的资源。3. MemoryRouter: 就是没有URL的情况,比如(React Native)。react-router的哲学 https://github.com/rccoder/bl...1. 动态路由,每一个route都是一个组件,更好的配合React 2. 路由嵌套react-router和redux问题 有时候,当location改变,组件并没有更新(子路由组件或者activity link),主要是因为:1.组件直接通过redux的connect 2.该组件不是路由组件,也就是没有这样的代码 <Route component={SomeConnectedThing}/>原因是redux内部实现了shouldComponentUpdate,但又没有从react-router接收到props,意味着不会改变。解决办法:// beforeexport default connect(mapStateToProps)(Something)// afterimport { withRouter } from ‘react-router-dom’export default withRouter(connect(mapStateToProps)(Something))

February 12, 2019 · 1 min · jiezi

使用redux,react在纯函数中触发react-router-dom页面跳转

文章有错误和不合理的地方欢迎小伙伴轻拍看到标题,很多react选手可能就会笑了,这还是问题吗?在函数中触发页面跳转不就的用redux吗!或者redux类似的控件,mbox,dva,rxjs等等,或者自己写个订阅功能的控件,可能就是因为太简单了,网上的解决这个问题的文章才那么少。当我试着用react搭建前端框架,这个问题确实困扰了我好久,当接触到redux就是这redux是正解了。痛点这就是困扰我的问题对fetch()进行封装,并对请求的返回数据做拦截,当捕捉到错误的时候,判断错误的状态码,404时让页面跳转到404页面,当时401时跳转到登录页面,500调整到500页面。 react-router ^4并没有暴露出来history对象,这让非组件内页面跳转变的困难。问题的解决定义storefunction navTo(state = “/”, action) { switch (action.type) { case ‘NAV_TO’: return action.path; default: return state }}let store = createStore(combineReducers({navTo}));export default store;fetch()状态拦截代码import store from “../../redux/store”;fetch(builUrl(url, params), requestInit) .then(data => { return data.json() }).catch(e => { const status = e.name; if (status === 401) { store.dispatch({type: ‘NAV_TO’, path: ‘/login’}); return; } if (status === 403) { store.dispatch({type: ‘NAV_TO’, path: ‘/exception/403’}); return; } if (status <= 504 && status >= 500) { store.dispatch({type: ‘NAV_TO’, path: ‘/exception/500’}); return; } if (status >= 404 && status < 422) { store.dispatch({type: ‘NAV_TO’, path: ‘/exception/404’}); return; } })app.js实现对store的订阅,并跳转页面import React, {Component} from ‘react’;import store from ‘./app/common/redux/store.js’import {withRouter} from “react-router-dom”;@withRouterclass App extends Component { constructor(props) { super(props); store.subscribe(() => { this.props.history.push(store.getState().navTo); }); } render() { return ( <div> {this.props.children} </div> ); }}export default App;当fetch()拦截到错误就可以进行页面调整了如果对redux有疑问,可以看我另一篇文章https://segmentfault.com/a/11… 这就是在函数中通过订阅的方式来实现页面跳转,easy easy !!!小伙伴可以举一反三运用到更多的地方去!!????????????????????如果能帮助到小伙伴的话欢迎点个赞????????????????????????????????????????如果能帮助到小伙伴的话欢迎点个赞???????????????????? ...

January 24, 2019 · 1 min · jiezi

React组件卸载、路由跳转、页面关闭(刷新)之前进行提示

React组件卸载生命周期、路由跳转和页面关闭三者看起来有些类似的地方,比如都是当前组件即将从视口消失,但实际上所触发的事件均不相同。以一个实际案例出发:某单页应用的文章编辑页用户正在编辑文章,此时尚未保存。当用户不小心要跳转到另外一个路由时需要提醒用户是否继续跳转,这个过程需要触发路由跳转以及组件卸载;而用户不小心点了关闭标签页按钮,或刷新了页面。这个过程触发了页面卸载事件;在这个案例中我们需要实现:1. 用户跳转页面时弹出提示框(路由采用histroy模式)2. 用户关闭页面时弹出提示框componentWillUnmount首先这个钩子函数是在组件卸载前调用的一个函数,它并不能阻止当前组件的卸载。所以不要想方设法在这里做提示,因为即便提示了,组件还是会卸载,文章还是会消失。路由守卫-<Prompt/>为了实现第一个功能,需要一个跳转路由之前进行的判断。在react-router-dom 4.0 之后取消了先前的路由守卫(其实我没研究过之前版本的,这个描述摘自网络)。在react-router-dom 4.0之后,实现这个功能可以依靠<Prompt/>组件。文档链接↗把这个组件添加到你的文章编辑页组件的任意部分import {Prompt} from ‘react-router-dom’;const Editor=()=>{ return ( <div> <Prompt when={true} message={location => ‘文章要保存吼,确定离开吗?’} /> </div> )}这里有一点需要注意,使用<Prompt/>时,你的路由跳转必须通过<Link/>实现,而不能依靠<a/>原生标签。点击取消时就会留在当前页面。至此已经实现了路由跳转时提醒用户进行保存的功能。窗口关闭事件-beforeunload实现第二个功能需要依靠对窗口的监听。React应用中对于窗口事件的应用远没有DOM事件频繁,所以好久没碰到还是有点手生的。最关键的就是,应该在何时进行监听?应该在组件挂载时监听事件,组件卸载时移除事件监听。因为我已经开始全面采用hooks新特性了,所以这里使用到useEffect。import React,{useEffect} from ‘react’;const Editor=()=>{ //监听窗口事件 useEffect(() => { const listener = ev => { ev.preventDefault(); ev.returnValue=‘文章要保存吼,确定离开吗?’; }; window.addEventListener(‘beforeunload’, listener); return () => { window.removeEventListener(‘beforeunload’, listener) } }, []); //return …}这里有几个需要注意的地方:useEffect第二个参数为空数组,表示只调用了componentDidMount和componentWillUnmount两个钩子事件监听和移除的第二个参数为同一个事件处理函数在beforeunload事件中的confirm,prompt,alert会被忽略。取而代之的是一个浏览器内置的对话框。(参考:MDN|beforeunload)必须要有returnValue且为非空字符串,但是在某些浏览器中这个值并不会作为弹窗信息

January 16, 2019 · 1 min · jiezi

运维记录1——解决在Nginx下部署CRA项目,二级目录不能访问的问题

如果从头开始搭建React项目,create-react-app通常是开发者的首选。毕竟不是谁都有精力去了解WebPack的复杂配置,而CRA将配置隐藏开箱即用的特性必然会受到普遍欢迎。根目录访问到了部署阶段,我通常使用nginx作为web容器,将项目部署到一个根目录下访问。如# nginx配置server { listen 80; server_name my.website.com; … location / { alias /data/www/react-project/dist; index index.html }}那么只要我们将项目文件放到对应的目录下,重启nginx即可开始访问web页面。二级目录访问有时我们有多个web项目,多个项目不可能同时挂在根目录下,所以我们会划分二级目录来分别访问各个web项目。如http://my.website.com/project1 => 访问react-project1项目http://my.website.com/project2 => 访问react-project2项目问题1:CSS等资源加载失败此时,如果简单将nginx配置的location改为/project1,则会出现网页无法访问的错误。# nginx配置server { listen 80; server_name my.website.com; … # location / { location /project1 { alias /data/www/react-project/dist; index index.html }}现象从dev工具可以看出,html文件有取得,但css、js等资源引用失败。css和js的文件路径都是http://my.website.com/static/…(或css)。分析CRA(create-react-app)的项目配置默认是跑在根目录下的。如果查看dist目录下的html会发现,所有的css或js文件的引用路径都是/开头的绝对路径。解决将打包路径从绝对路径改为相对路径:# package.json{ … “homepage”: “.”, // 添加homepage属性,将路径改为当前目录 …}重新编译后看到,所有的资源文件路径都改过来了。问题2:加载成功,网页空白重新上传到服务器,更新dist目录下的文件,重启nginx后访问网页。现象结果发现,网页仍然是空白一片。查看html的渲染结果,发现似乎js并没有执行。分析在react-router-dom的例子中,通常使用的是BrowserRouter。这种类型的Router在向服务器发送请求时,如果相对于二级目录的路由去指向对应的页面路由,就会找不到资源,因此也就不会渲染。解决BrowserRouter有一个属性叫做basename,就是用于解决此类问题。…import { Route, BrowserRouter as Router, Switch, Redirect } from ‘react-router-dom’;…… <Router basename=’/project1’> <Switch> <Redirect exact key=‘index’ path=’/’ to=’/home’ /> { routes } </Switch> </Router>…问题3:访问成功,刷新后404修改以上配置并编译部署,重启nginx后可正常访问网页。但刷新后,网页变为一片空白。现象网页显示,在请求页面路由如http://my.website.com/project… 时,该路由的请求状态为404。分析还是因为BrowserRouter的问题,之前能正常访问时因为路由中设置了Redirect,所以能访问到根目录并自动跳转到/home。但直接访问则会访问失败。解决在nginx配置中加入try_files命令 location /project1 { alias /data/www/react-project/dist; # index index.html try_files $uri /project1/index.html }这样,在请求$uri时如果找不到对应的资源,会fallback回去加载index.html。问题解决。 ...

January 11, 2019 · 1 min · jiezi

reactjs单页应用同级路由切换scrollTop

问题:单页应用开发时,当在A页面滚动滚动条后,点击进入B页面,滚动条保持在A页面的滚动位置。目标:同级路由切换时,滚动条回滚到页面顶端。解决方案://在componentDidMount周期添加scrollTo()class Home extends Component{ componentDidMount(){ window.scrollTo(0, 0); }}

December 19, 2018 · 1 min · jiezi

看完React文档后,重写了下CnodeJS社区,感觉看上去还不错

Github DEMO 欢迎Star一个 React 的初/中级练习项目:重构 CnodeJS 社区这里简述下我学习 React 的方式:看了一边文档,把‘主要概念’全部看完,‘高级指引’里的根据个人兴趣挑了一些看了看。紧接着就动手写此项目(大概花了 3 天的业余时间完成)在此期间根据需要,看了 React-Router 文档,了解了 Redux 的实现原理(但本项目并没有用 Redux)(歪个楼:“我相信任何复杂技术背后的原理都是简单易懂的”)P.S. 如果你想入门 React,但苦于没有难度合适的项目的话,It’s For You!(考虑到别人可能会看我源码来学习,我补充了“非常详细的注释”)P.P.S. 朋友看到后吐槽了句“怎么不是cnode,就是v2ex”(我补充了下“爬虫的话就是煎蛋? ”)XD

December 4, 2018 · 1 min · jiezi

React-Keeper 前端路由缓存 存储状态(大部分转)

前言接触react也有一段时间了,一直在做关于react前端架构相关的研究,由于工作性质,有些干货只能自己研究了,今天遇见了一个需求:在做后台管理项目的时候,产品经理提出:从列表页填写查询条件,然后查询出结果,点击某一条结果进入编辑页面,编辑完了之后返回列表页,还想看到之前查询的条件和查询的结果;(目前是返回直接刷新页面,等于查询条件为空)。那么团队的解决办法是,在跳转到编辑页面的时候,在浏览器打开新的标签(不过结合之前的架构(有点老),这个虽然。。但是也可以解决问题)接触过vue的同学知道 vue有一个keep-alive可以缓存组件状态,在做移动端应用的时候非常方便,提高性能;那么react有没有这样一个东西呢?当然有,那就是React-Keeper了github地址 https://github.com/vifird/rea…下面就是转载的内容了了解React的同学一定了解React-Router,这个几乎是React单页面应用必备的路由框架。如果有足够多的开发经验,你一定会发现React-Router的很多问题,比如:没有页面缓存、不能传递属性、脱离JSX的动态加载和过滤器实现等,这些问题尤其在移动端表现问题更多。这里我们来推荐一款更强大的React路由器:React-Keeper,一个比React-Router更灵活、更适用于移动端、路由功能更健壮的框架,React-Keeper除了基础功能更强大以外,特别对移动APP的路由做了增强,能够满足更丰富的移动端场景。React-Keeper吸收了React-Router的思想,使用方式与React-Router相似度很大,都提供了Route组件和Link组件,基本可以实现React-Router的平滑迁移。React-Keeper的基础教程,可以参考其Github : Github [React-Keeper],这里我重点介绍一下React-Keeper的特性。特性介绍1.可扩展路由允许你在任何时间、任何组件内添加路由配置。如下面:我们可以在路由匹配的的组件Products中再添加路由组件。这种特性,对团队合作开发很友好,可以让路由配置也按模块化的切分;也非常适用于有动态加载需求的大型网站。(这个特性在React-Router最新版中也已经得到了支持)const App = ()=> { return ( <HashRouter> <div> <Route component={ Home } path="/"/> <Route component={ Products } path="/products"/> </div> </HashRouter> ) } const Products = ()=> { return ( <div> <Route component={ ScienceProducts } path="/sci" /> <Route component={ DailiUseProducts } path="/dai" /> </div> ) } ReactDOM.render(<App/>, document.getElementById(‘root’))2.页面缓存在移动开发中,我们经常会遇到这样的场景:在一个列表页浏览了很久,点击一项进入详情页,然后再返回到列表页,这时候我们希望列表页能保留在之前的状态(滚动位置、临时操作等),React-Router无法解决这个问题,在返回后列表页的DOM要重新加载,所以我们不得不重新手动找回之前的状态(滚动到之前的位置)。这里我们需要一个页面缓存机制来解决这个问题。所谓页面缓存,即当地址与路由不匹配时,自动缓存页面的状态,当匹配时,再对页面进行还原。页面缓存是React-Keeper的一个重要特性,其内部集成了缓存管理器,可以对路由组件的绑定与解绑进行代理,从而实现了页面缓存。React-Keeper提供了3种页面缓存方式,下面我们来分别进行介绍。2.1 cache属性所有添加了cache属性的路由组件,React-Keeper缓存管理器都会页面进行代理。在下面的示例中,Home、AboutUs页面会使用缓存代理:class App extends React.Component { render() { return ( <HashRouter> <div> <Route cache component={Home} path=’/’/> <Route component={Host} path=’/host’ /> <Route cache=‘parent’ path=’/aboutus’ component={AboutUs}/> </div> </HashRouter> ) }} ReactDOM.render(<App/>, document.getElementById(‘root’))cache属性可以添加属性值,React-Keeper支持的属性值有root(default)、parent。cache=‘root’(或cache)为永久缓存,只要根组件不解绑,页面将永久缓存。cache=‘parent’为父组件缓存,在父组件不解绑的情况下会维持缓存状态。2.2 CacheLink组件React-Keeper额外提供了CacheLink组件,继承自Link,故有Link组件的所有特性,此外,其内部对接了缓存管理器,可以对链接跳转环节进行代理。CacheLink缓存为临时缓存,当使用其新打开页面时,缓存管理器会临时缓存链接的来源页面,当返回时至之前页面(或路由状态变更)时,提取缓存页面以展示,并清除缓存。这种特性适用于非常用列表页的缓存,使用方式如下:<ul className=‘nav navbar-nav’> <li><Link to=’/’>Home</Link></li> <li><CacheLink to=’/product/ASDFADF’>Detail</CacheLink></li></ul>3.标签化过滤器在React-Keeper中,我们可以为每一个Route组件单独定义多个过滤器,当过滤器验证通过后才能进行下面的操作,Route支持两类过滤器:绑定过滤器、解绑过滤器。过滤器的使用场景,最常用的应该就是登录验证,对于某些需要登录后才能访问的资源,我们希望登录检测通过后再进行页面绑定,而不是先跳转页面再进行验证。下面是React-Keeper官网登录过滤的示例代码:// Define a fllter, and run over it or not. // receive ‘props’const loginFilter = (callback, props)=> { if(!props.host) { // dynamicly request data (use jQuery ajax) $.ajax({ url: ‘host/login.do’, data: {}, succeed: function(data){ if(data.host){ // run ‘callback’ function to enter next step (render component or next filter) callback() } }, error: function(){ }, dataType: ‘json’ }) }} // Added to Route Component// Single Filter<HashRouter> <Route path=’/user’ component={User}, enterFilter={ loginFilter } /></HashRouter> // Multiple Filters<HashRouter> <Route path=’/user’ component={User}, enterFilter={[ loginFilter, permitFilter1, permitFilter2 ] } /></HashRouter>4.标签化动态加载React-Keeper支持动态组件加载,而动态加载使用方式也是非常简单,可以直接在Route组件行进行操作。使用方式如下:<Route loadComponent={ (callback)=>{ System.import(’../Products.js’).then((Products)=>{ callback(Products) }) } } path=’/products’> 在React-Keeper的内部处理中,当path匹配的时候,才会进行文件的加载,这对于大型的WEB应用无疑是非常必要的。注意:过滤器的运行,在动态文件加载之后。5.灵活的配置React-Keeper的Route组件支持自定义属性,并会将所有自定义的属性传递给要渲染的组件。React-Keeper的配置相当灵活,可以全部采用组件属性化的配置,比如index、cache、miss等,以下是Route组件所有的保留词:index : 入口组件miss : 地址不匹配时渲染的组件cache : 缓存标记redirect : 重定向地址 (当组件满足渲染条件时才会执行)path : 匹配地址规则component :要匹配的组件loadComponent : 动态加载组件enterFilter : 挂载过滤器leaveFilter : 卸载过滤器offDirtyCheck : 关闭脏检查。React-Keep会默认启用脏检查,以避免地址变更时不必要的渲染<HashRouter> <div><Route index component={Home} path=’/’/><Route cache component={Host} path=’/host’ /><Route miss path=’/aboutus’ component={AboutUs}/><Route path=’/other’ redirect=’/redirect’/></div></HashRouter>写在最后读React-Keeper源码,发现内部有几点值得React开发者借鉴的地方:可扩展路由的实现方式采用了订阅模式,进行Route的集中管理,通过减少监听事件保证了路由管理的效率。默认使用数据脏检查,避免不必要的渲染。缓存管理是重要的一个核心功能,React-Keeper内部集成了两个缓存管理器,并在每次地址变更时对缓存进行清理。集成了地址匹配缓存以提高匹配的效率。无状态组件(Stateless Component)的管理,使用react-funtional库将组件转换为有状态组件的方式。React-Keeper还是一个比较新的框架,国内外实践的人还比较少。从源码级别看其实现,在前端世界众多而杂乱的开源框架中,算是质量很高的一个。附录Github : https://github.com/vifird/rea… ...

October 10, 2018 · 2 min · jiezi