乐趣区

关于react.js:React-高级指引的学习笔记

无障碍

对于无障碍局部,没有深刻进去钻研和剖析,集体认知是所有的性能按钮,操作都须要尽量贴合所有用户,对具备某些欠缺的用户也能有足够敌对的浏览体验,比方所有的鼠标操作,都可能具备键盘管制等等,后续如果深入研究,再补充。

代码宰割

在钻研代码宰割钱,首先须要明确什么是打包,作为一个初学者,应用过的框架只有 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 的两个局部 Suspenselazy , 你能够通过如下两种形式来应用它:

/**
 * @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";

@withRouter
class 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;

次要是通过 componentDidCatchstatic getDerivedStateFromError 来获取谬误。

Refs 转发

未完待续。。。

退出移动版