都说 React 开发效率高,但效率高在哪呢?来细看看。

用 d3 写一个 List:

const renderList = data => {
d3.select("ul")
.selectAll("li")
.data(data, d => d.id)
.join(
enter => enter.append("li").text(d => d.text),
update => update.text(d => d.text),
exit => exit.remove()
);
};

d3 把 view 和 data 的关系分为 3 种:

  • enter:有 data 没 view
  • update:有 data 有 view
  • exit:有 view 没 data

数据更新,开发者需考虑「新 view」对比「老 view」,新增的「enter」、更新的「update」、减少的「exit」要怎么处理。


用 React 来写:

const List = ({ data }) => {
return (
<ul>
{data.map(d => (
<li key={d.id}>{d.text}</li>
))}
</ul>
);
};

数据更新,开发者只需考虑「新 view」是什么样,不用考虑怎么把「老 view」变成「新 view」,比 d3 简单。


React 是不是比 d3 好用?

答:不一定,要看场景。React 框架把「新增的、更新的、减少的处理」都做了,开发者没法干预。但如果你想做一些动画,需要精细控制「新增的、更新的、减少的」,React 就不如 d3 好用了。

再看 React 代码:

const List = ({ data }) => {
return (
<ul>
{data.map(d => (
<li key={d.id}>{d.text}</li>
))}
</ul>
);
};

React 把组件简化成了一个函数,data -> view。组件就是函数,意味着函数可以怎么玩,组件就可以怎么玩。

  • 函数内调用别的函数

    function a() {}
    function b() {} function c() {
    a();
    b();
    }
    function A() {}
    function B() {} function C() {
    return (
    <div>
    <A />
    <B />
    </div>
    );
    }
  • 函数的返回值作为别的函数的传参

    function a() {}
    function b(arg) {} function c() {
    b(a());
    }
    function A() {}
    function B({ children }) {
    return <div>{children}</div>;
    } function C() {
    return (
    <B>
    <A />
    </B>
    );
    }
  • 高阶函数

    function memoize(fn) {
    const cache = {};
    return arg => {
    if (cache[arg]) return cache[arg];
    else {
    const result = fn(arg);
    cache[arg] = result;
    return result;
    }
    };
    } const memoizedSqrt = memoize(Math.sqrt);
    const A = () => {};
    const wrapper = Cmp => {};
    const WrappedA = wrapper(A);
  • Continuation,或者叫 Callback。Callback 的特点是:等时机成熟后才执行。

    const handler = () => {};
    button.addEventListener("click", handler);
    // Context Consumer
    <ThemeContext.Consumer>
    {theme => <Cmp theme={theme} />}
    </ThemeContext.Consumer>
    // Render Props
    const MouseTracker = Cmp => {
    return (
    <Mouse
    render={mouse => <Cmp mouse={mouse} />}
    />
    );
    };
  • 递归

    const factorial = n => {
    if (n === 1) return 1;
    else return n * factorial(n - 1);
    };
    const Tree = ({ data }) => (
    <ul>
    {data.map(d => (
    <li key={d.id}>
    {d.text}
    {d.children && <Tree data={d.children} />}
    </li>
    ))}
    </ul>
    );

React 组件的种种用法,本质都是函数的用法。从函数的角度来理解、运用 React,就不会觉得这个框架很神秘了。

聊聊 React的更多相关文章

  1. 聊聊React高阶组件(Higher-Order Components)

    使用 react已经有不短的时间了,最近看到关于 react高阶组件的一篇文章,看了之后顿时眼前一亮,对于我这种还在新手村晃荡.一切朝着打怪升级看齐的小喽啰来说,像这种难度不是太高同时门槛也不是那么低 ...

  2. 聊聊React的路由React-Router、react-router-dom

    关于二者的区别 参见:https://github.com/mrdulin/blog/issues/42 直接使用react-router-dom好了,react-router-dom封装了react ...

  3. Vue.JS React 精彩文章汇总

    JavaScript深入系列  [干货] JavaScript数组所有API全解密  [干货] 移动端:页面->手淘互动动效的探索 - IT大咖说 - 大咖干货,不再错过 [扫盲] Jonath ...

  4. React Native踩坑日记 —— tailwind-rn

    项目背景 在项目的初始阶段,我们需要建立自己的design system,我们spike了一些方案,tailwind-rn就是其中一种,如果有用到或者即将用到tailwind-rn的,可以进来看一看, ...

  5. React Native纯干货总结

    随着项目也渐渐到了尾声,之前的项目是mobile开发,采用的是React Native.为即将要开始做RN项目或者已经做过的小伙伴可以参考借鉴,也顺便自己做一下之前项目的总结. 文章比较长,可以选择自 ...

  6. 【react】什么是fiber?fiber解决了什么问题?从源码角度深入了解fiber运行机制与diff执行

    壹 ❀ 引 我在[react] 什么是虚拟dom?虚拟dom比操作原生dom要快吗?虚拟dom是如何转变成真实dom并渲染到页面的?一文中,介绍了虚拟dom的概念,以及react中虚拟dom的使用场景 ...

  7. React在开发中的常用结构以及功能详解

    一.React什么算法,什么虚拟DOM,什么核心内容网上一大堆,请自行google. 但是能把算法说清楚,虚拟DOM说清楚的聊聊无几.对开发又没卵用,还不如来点干货看看咋用. 二.结构如下: impo ...

  8. 再谈React.js实现原生js拖拽效果

    前几天写的那个拖拽,自己留下的疑问...这次在热心博友的提示下又修正了一些小小的bug,也加了拖拽的边缘检测部分...就再聊聊拖拽吧 一.不要直接操作dom元素 react中使用了虚拟dom的概念,目 ...

  9. 聊聊CSS postproccessors

      阿里妈妈 @一丝 准备发布其CSSGrace,即CSS后处理插件,于是顺便聊聊CSS postprocessors. 从Rework说起 Rework是TJ大神开发的CSS预处理框架.但为什么会出 ...

随机推荐

  1. SpringBoot基于EasyExcel解析Excel实现文件导出导入、读取写入

    1. 简介   Java解析.生成Excel比较有名的框架有Apache poi.jxl.但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题 ...

  2. 【C#】DockPanelSuite 中 DockState.Document 状态下子窗体控件不显示的解决方案

    DockPanelSuite 是 Winform 中优秀的布局控件,但是这次使用过程中却出了个问题. 我遇到的问题是这样的,主窗体是通过 ShowDialog 显示的,子窗体的停靠状态为 DockSt ...

  3. G1 收集器

    基础知识 性能指标 在调优Java应用程序时,重点通常放在两个主要目标上:响应性 或 吞吐量. 响应性Responsiveness 是指应用程序对请求的数据做出响应的速度: 桌面用户界面对事件的响应速 ...

  4. 什么是babel

    什么是babel babel是一款基于node开发的工具,其功能是对es6的新语法和新特性进行转码.

  5. rbd锁引起kvm虚拟机无法启动的故障

    前言 环境因为一些问题(网络,或者磁盘,或者其它各种异常),引起了集群的状态的一些变化,变化之后,集群的某些虚拟机正常某些虚拟机出现异常,异常现象就是无法启动 特别是win server2008 ,会 ...

  6. [日常摸鱼]luogu1613跑路

    新年A的第一道题2333 https://www.luogu.org/problemnew/show/P1613 题意:给一张有向图,每条边长为1,每个单位时间只能走$2^k$的长度,$k$可以任意选 ...

  7. linux里用户权限:~$,/$,~#,/#的区别与含义

    $表明是非root用户登录,#表示是root用户登录,它们是终端shell的命令提示符几种常用终端的命令提示符 BASH:  root账户: # ,非root账户: $KSH:  root账户: # ...

  8. alibaba-sentinel-1.8变化

    maven最新坐标 <dependencies> <dependency> <groupId>org.springframework.boot</groupI ...

  9. 微服务痛点-基于Dubbo + Seata的分布式事务(TCC模式)

    前言 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata 将为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案. ...

  10. 【SpringBoot—注解】@requestBody 与@requestparam;@requestBody的加与不加的区别

    一)首先说明xia @requestBody与@requestParam的区别 spring的RequestParam注解接收的参数是来自于requestHeader中,即请求头.都是用来获取请求路径 ...