从 loading 的 9 种写法谈 React 业务开发

banner

前言

这是一篇比较全面讲解 React 的文章,里面不少基础知识但愿你本身一边查阅资料一边学习。全文从业务开发中最经常使用见 loading 效果不一样是实现讲起,说下如今前端开发在业务上应该有的思考。html

入门级操做

State

最简单的实现,咱们在 Loading 组件内部声明一个状态,经过代码逻辑判断 loading 效果的展现。前端

export default class extends Component {
  ...
  render() {
    return this.state.loading ? <div className="loader" /> : <div>finish</div>;
  }
}

完整演示react

Props

随着业务的发展,这个 Loading 组件用到的地方会很是多,上面这个代码耦合了不少逻辑,为了让这个组件可以很好的复用,那咱们抽离出组件的业务逻辑,将内部状态进行提高,那这个组件就是一个能被复用的 UI 组件。git

export default function(props) {
  return props.loading ? <div className="loader" /> : <div>finish</div>;
}

完整演示github

注:上面两段代码你可能会想,为何 FuncClass 都能实现一个组件,他们有什么差异吗?
其实你在开发时不容易感受到差异,但 React 自己是进行了不少差异处理,若是是 Class 类,React 会用 new 关键字实例化,而后调用该实例的 render 方法,若是是 Func 函数,React 会直接调用它。编程

Refs

若是你是一个 jQuery 转型 React 的开发,会很天然的想到,我找到 Loading 组件的节点,控制他的显示与隐藏,固然这也是能够的,React 提供 Refs 方便你访问 DOM 节点 或 React 元素。redux

export default class extends Component {
  componentDidMount() {
    fetch().then(() => {
      this.el.changeLoading(false);
    });
  }

  render() {
    return (
      <Loading ref={el => { this.el = el; }} />
    );
  }
}

完整演示前端框架

通用逻辑抽离

当你的应用作到必定的复杂度,不一样的页面都会有 loading 效果,你确定不但愿每一个页面都重复的书写同样的逻辑,这样会致使你的代码重复且混乱。框架

React 中有两个比较常见的解决方案 HOCRender Props,其实这两个这两个概念都是不依赖 React 的。dom

让咱们暂时忘掉 React,下面我对 HOCRender Props 写两个例子,你会发现组件复用是如此简单。

HOC

HOC 其实就是一种装饰器模式,它接受一个组件做为参数,而后返回相同的组件,这样就能够额外增长一些功能。

const func = () => {
  console.log("func");
};

const wrap = func => {
  console.log("wrap");
  return func;
};

// wrap 逻辑已被复用
wrap(func)();

完整演示

Render Props

Render Props 就是咱们给一个函数传递一个回调函数作为参数,该回调函数就能利用外面函数的执行结果作为参数,执行任何操做。

const func = param => {
  console.log("func");
};

const wrap = (param, func) => {
  console.log("wrap");
  func(param);
};

// wrap 逻辑已被复用
wrap("", func);

完整演示

相同点:

  • 二者都能很好的帮助咱们重用组件逻辑
  • 和回调函数相似,当嵌套层数不少时,会形成回调地狱

不一样点:

  • HOC 和 父组件有相同属性名属性传递过来,会形成属性丢失;
  • Render Props 你只须要实例化一个中间类,而 HOC 你每次调用的地方都须要额外实例化一个中间类。

总的来讲,在须要复用组件逻辑的时候,我我的更倾向于 Render Props 的方式。

复杂状态管理

当你的应用愈来愈大,组件之间交互愈来愈复杂,那整个页面的数据逻辑将变得难以管理,这时候为了方便管理应用的状态,你能够选择一些状态管理工具,例如 ReduxFluxdva 等。

Redux

Redux

我不太想谈这些数据流框架,由于他们的概念 actionstoredispatch 太过于生涩难懂。
现代前端框架 React 和 Vue 其实都是一个套路,经过数据渲染试图,而后视图上操做反过来更新数据,从新渲染视图,刷新页面。
数据叫作 store,动做叫作 ation,触发行为叫 dispatch,而后数据到视图的渲染由 React/Vue 处理的。

(图片来自 这里

// reducers.js
const initialState = {
  loading: false
};

export default function reducer(state = initialState, action) {
  switch (action.type) {
    case "CHANGE_LOADING":
      return {
        loading: action.payload
      };
    default:
      return state;
  }
}

完整演示

Saga

当你代码中有大量的异步操做时,例如 fetch 请求,你确定会想到事件监听回调函数发布/订阅
很好,上一个例子其实就是事件监听的处理方式,而后回调函数的主流的解决方案是 redux-thunk,而发布/订阅的主流解决方案是 saga

import { takeLatest, put } from "redux-saga/effects";

import fetch from "./fetch";

function* fetchInfo(action) {
  yield put({
    type: "CHANGE_LOADING",
    payload: true
  });

  yield fetch();

  yield put({
    type: "CHANGE_LOADING",
    payload: false
  });
}

export default function* fetchSaga() {
  yield takeLatest("FETCH_REQUEST", fetchInfo);
}

完整演示

当你耐心看到这里,我知道你对 React 确定有必定的经验,如今还能够作不少,例如把 loading 状态提高到 Store 的顶部,那整个站点就只有一个 loading 了,而后你还能够将 fetch 再封装一个 HOC 修改 loading 状态,这就是一个相对完美的 loading,其实 React 业务开发均可以用这个套路。

新的 API

Context

context

上面 redux 的例子是否是过于复杂
对于简单的业务,虽然有不少页面,嵌套层次也很复杂,你固然能够不用状态管理工具,你能够试着使用 Context,它能够方便你传递数据,它其实就是 Render Props 的一种实现。

export default React.createContext({
  loading: false,
  changeLoading: () => {}
});

完整演示

Hooks

写到这,静一下,是否是哪里作错了什么?

个人业务只是想写个简单的 loading 效果,却了解了一堆组件生命周期的概念。

Hooks 恰好帮你解决了这样的问题,Hooks 能容许你经过执行单个函数调用来使用函数中的 React 功能,让你把面向生命周期编程变成面向业务逻辑编程

import React, { useState, useEffect } from "react";

import Loading from "./Loading/index";
import fetch from "./fetch";

function App() {
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch().then(() => {
      setLoading(false);
    });
  }, []);

  return <Loading loading={loading} />;
}

export default App;

完整演示

好好总结

上面对每一个点都作了具体实现,但他们都不是隔离的,你能够根据你的认知和业务特色总结抽象一套本身的方法论;

多了解多抽象多思考,练就十八般武艺,遇到问题的时候才能游刃有余;

React 如今宣传的东西愈来愈多,你最好先深刻了解他们,而后用批判的眼光,保持理智,防止本身天天用很新的特性重构你本身的代码。

参考文章

React 官网

When do I know I’m ready for Redux?

文章可随意转载,但请保留此 原文连接

很是欢迎有激情的你加入 ES2049 Studio,简历请发送至 caijun.hcj(at)alibaba-inc.com 。

相关文章
相关标签/搜索