聊聊 React

  • A+
所属分类:Web前端
摘要

都说 React 开发效率高,但效率高在哪呢?来细看看。用 d3 写一个 List:d3 把 view 和 data 的关系分为 3 种:

都说 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

聊聊 React

数据更新,开发者需考虑「新 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,就不会觉得这个框架很神秘了。