无障碍
对于无障碍局部,没有深刻进去钻研和剖析,集体认知是所有的性能按钮,操作都须要尽量贴合所有用户,对具备某些欠缺的用户也能有足够敌对的浏览体验,比方所有的鼠标操作,都可能具备键盘管制等等,后续如果深入研究,再补充。
代码宰割
在钻研代码宰割钱,首先须要明确什么是打包,作为一个初学者,应用过的框架只有webpack,对于React来说,有一个create-react-app可能很不便的实现一个简略的我的项目搭建,而我的项目搭建实现后,对于比较简单的单页面利用或者没有额定需要的我的项目来说,不须要进行优化,如果须要进一步进行配置,能够通过下列代码进行裸露配置:
npm run eject 或者 yarn eject
应用何种办法看各自的配置,在裸露后的文件中进行相应的配置即可,具体实现,等前面如果有深入研究再写。而react中代码宰割次要讲的还是通过 import 来优化打包。至于为什么不是require,我也不分明,不过这篇文章require和import的区别中写的比拟清晰,集体认为是兼容性以及es6标准的思考。
罕用的import引入模块形式有很多:
import Comp from './Component' //引入自定义组件import { Button } from 'antd' // 引入模块import * as d3 from 'd3' // 引入模块内所有,以d3作为对象import Img from '../../../assets/images/test.png' //引入图形
通过 import 引入的内容,如果是用create-react-app创立的我的项目,则在 webpack 打包时会主动进行宰割,若果不是,就本人去搜寻一下怎么配,网站上举荐了代码宰割网站。
前面才是我认为的这节的重点 —— React.lazy(懒加载)。前文曾经提到了组件通过失常的 import 引入,而懒加载的实现次要是依赖于 React 的两个局部 Suspense 和 lazy ,你能够通过如下两种形式来应用它:
/** * @desc 办法1 */import React, { Component, Suspense, lazy } from "react";// ps:常量定义在import之后const Comp = lazy(() => import("@/pages/Comp"));class Test extends Component { render() { return ( <> <Suspense fallback={<div>loading...</div>}> <Comp /> </Suspense> </> ); }}/** * @desc 办法2 */import React, { Component } from "react";// ps:常量定义在import之后const Comp = React.lazy(() => import("@/pages/Comp"));class Test extends Component { render() { return ( <> <React.Suspense fallback={<div>loading...</div>}> <Comp /> </React.Suspense> </> ); }}
ps:在应用lazy后,必须跟上Suspense包裹在外层
同时,Suspense内不是只能有一个lazy对象,他能够是多个对象,就是说只有在最外层应用了该模块,同一组件下的所有lazy都能被渲染进去,这在定义路由的时候尤为无效:
/** * @desc 懒加载联合路由导航 */import React, { Component, Suspense } from "react";import { Switch, Route, Redirect, withRouter } from "react-router-dom";import routes from "@/routes";// import Navigation from "@/components/Navigation";import { filiterRoutes } from "@/util";import { message } from "antd";@withRouterclass RouteOption extends Component { judgeRoute = (route, path) => { let bool = false; route && route.length > 0 && route.map((v) => { if (v.href === path) { bool = true; } return v; }); return bool; }; renderRoute = (routeslist) => { return ( <Switch> {routeslist.map((item, index, arr) => { if (arr.length > index + 1) return ( <Route key={item.path} path={item.path} exact={true} component={(props) => <item.component {...props} />} ></Route> ); else { return ( <Switch key={item.path}> <Route path={item.path} exact={true} component={(props) => <item.component {...props} />} ></Route> <Redirect from="/*" to="/home" /> </Switch> ); } })} </Switch> ); }; render() { return ( <Suspense fallback={<div>loading...</div>}> {this.renderRoute(routes)} </Suspense> ); }}export default RouteOption;
这并不是说你只须要在最外层定义一个Suspense包裹所有就能够完事了,如果你这样做了。。。。
/** @desc 这可真是太聪慧了,编程我不行,偷懒第一名*/import React, { Component, Suspense } from "react";......class App extends Component {...... render() { return ( <div className="App"> <Suspense> <Child /> </Suspense> </div> ); }}export default App;
这就是后果:
Context
尽管我总是感觉简略的高低层级传递参数用props这样的就行,页面间传递还有路由传参,或者是用redux、mobx等仓库组件,context有点鸡肋,然而还是看了一下,谁晓得当前会不会用上呢。
- 总的来说:context就相似于在最外层父组件包裹了一个公共数据,存储在最外层,这样,只有是被包裹的内层都能够去申请这个数据,也能依据这个数据的更新来同步更新组件,这样的形式防止了当你想要给重孙组件传递一个值时,你须要两头传递props3次:即父->子->孙->重孙,而context免去了这样的麻烦,只有在包裹内,你能够间接在重孙获取数据。
- 惋惜鸡肋的是,重孙不能操作数据的更改,所有变更都在最上层解决,这样的益处是防止了许多非可控的副作用,不好的点是,利用的中央我真的找不到多少(至多我是这样,可能接触的太少了)。
首先要应用createContext创立一个context对象,能够是简略的字符串,也能够是一个对象,不过不能是一个undefined的值。
const PowerContext = React.createContext("admin");const PowerContext = React.createContext({ name: "测试", sex: "female", age: 20,});
随后把须要用到这些值的组件用Provider包裹起来。
<PowerContext.Provider value={power}> <InfoContext.Provider value={info}> <Layout /> </InfoContext.Provider></PowerContext.Provider>
最初在须要应用该数据的子节点中应用Consumer进行获取
function Layout() { return ( <> <Content1 /> <Content2 /> </> );}function Content1() { return ( <PowerContext.Consumer> {(admin) => ( <InfoContext.Consumer> {(info) => { return admin === "admin" ? ( <div> <p>姓名:{info.name}</p> <p>性别:{info.sex}</p> <p>年纪:{info.age}</p> </div> ) : ( <p>你没有权限</p> ); }} </InfoContext.Consumer> )} </PowerContext.Consumer> );}
如此就实现了一个流程,即创立 => 包裹 => 调用
谬误边界
相当于组件的 try catch ,可能捕捉到组件的异样,而后展现设置好的备用UI界面,以防异样显示带来的损失。上面是一个简答的谬误边界组件demo:
/** * @desc 谬误边界demo * @name ErrorBoundary * @author WebTeacher * @date 2020/11/10 */import React, { Component } from "react";import styles from "./styles.module.less";class ErrorBoundary extends Component { constructor(props) { super(props); this.state = { hasError: false, error: "", errorInfo: "", }; } // 这个办法和上面应用其中一个就能够,而后我就用了比拟习惯的上面那种 // 在官网文档外面是阐明了渲染备用UI用这个,抛出异样用上面那个 static getDerivedStateFromError(error) { // 更新 state 使下一次渲染可能显示降级后的 UI return { hasError: true }; } // 获取异样并抛出 componentDidCatch(error, errorInfo) { this.setState({ error: error, errorInfo: errorInfo, }); } render() { if (this.state.hasError) { return ( <div> <h1>仿佛什么中央出了问题!</h1>; <details style={{ whiteSpace: "pre-wrap" }}> {this.state.error && this.state.error.toString()} <br /> {this.state.errorInfo.componentStack} </details> </div> ); } return this.props.children; }}export default ErrorBoundary;
次要是通过componentDidCatch和 static getDerivedStateFromError 来获取谬误。
Refs 转发
未完待续。。。