zoukankan      html  css  js  c++  java
  • React 核心思想之声明式渲染

    React 发展很快,概念也多,本文目的在于帮助初学者理清 React 核心概念。

    React 及 React 生态

    React 的核心概念只有 2 点:

    • 声明式渲染(Declarative)

    • 基于组件(Component-Based)

    声明式渲染

    声明式与命令式

    • 命令式编程:命令“机器”如何去做事情(how),这样不管你想要的是什么(what),它都会按照你的命令实现。

    • 声明式编程:告诉“机器”你想要的是什么(what),让机器想出如何去做(how)。

    举例:

    // 命令式关注如何做(how)
    
    var numbers = [1,2,3,4,5]
    
    var doubled = []
    
    for(var i = 0; i < numbers.length; i++) {
    
      var newNumber = numbers[i] * 2
      doubled.push(newNumber)
    
    }
    console.log(doubled) //=> [2,4,6,8,10]

    遍历整个数组,取出每个元素,乘以二,然后把翻倍后的值放入新数组,每次都要操作这个双倍数组,直到计算完所有元素。

    // 声明式关注做什么(what)
    
    var numbers = [1,2,3,4,5]
    
    var doubled = numbers.map(function(n) {
    
      return n * 2
    })
    console.log(doubled) //=> [2,4,6,8,10]

    map 函数所作的事情是将直接遍历整个数组的过程归纳抽离出来,让我们专注于描述我们想要的是什么(what)。

    模板渲染

    渲染:模板 => HTML => 页面视图

    发生在服务器的叫后端模板渲染,公司用的是velocity

    发生在客户端的叫前端模板渲染,常用的有 artTemplate

    以 artTemplate 为例。

    • 模板

    <script id="test" type="text/html">
        <div>
            <h2>北京时间: {{ date.toLocaleTimeString() }}.</h2>
        </div>
    </script>
    • 数据

    • 渲染

    setInterval(function() {
        // 数据
        var data = {
            date: new Date()
        };
        // 渲染(将数据和模板绑定在)
        var html = template('test', data);
        // 渲染
        document.getElementById('container').innerHTML = html;
    },100)

    React 声明式渲染

    和普通模板不同的是,React 模板写在 JS 文件中,而不是 html 的 <script> 标签中。能使用所有 JS 语法,而不只有模板语法,所以更加灵活。

    function formatName(user) {
      return user.firstName + ' ' + user.lastName;
    }
    
    // 数据
    const user = {
      firstName: 'Harper',
      lastName: 'Perez'
    };
    
    // 模板
    const element = (
      <h1>
        Hello, {formatName(user)}!
      </h1>
    );
    
    // 渲染
    ReactDOM.render(
      element,
      document.getElementById('root')
    );

    React 可局部渲染,且只渲染改变了的数据。纯模板只能整体渲染。

    高效的局部渲染意味着,开发者 只需要维护可变的数据 state (what) ,让 react 框架帮助我们处理 DOM 操作(what)。

    // React.createClass 创建模板容器(类)
    class Clock extends Component {
      render() {
          return (
              <div>
                  <h2>北京时间: { this.props.date.toLocaleTimeString() }</h2>
              </div>
          );
      }
    }
    
    setInterval(function() {
        // ReactDOM.render 渲染指令
        ReactDOM.render(
          // date 数据
          <Clock date={new Date()} />,
          document.getElementById('container')
        );
    }, 100);

    state 只用于存放可变的数据。

    通过 setState 告诉 react 什么数据变了,React 会自动更新数据改变部分的视图

    class Clock extends Component {
      // 初始化
      constructor(props) {
        super(props);
        // state 只用于存放可变的状态
        this.state = {date: new Date()};
      }
      // 初始化完成后执行
      componentDidMount() {
        setInterval(() => {
          // setState 在修改 state 参数后会自动调用 render 方法。
          this.setState({
            date: new Date()
          })
        },100)
      }
    
      render() {
          return <h2>北京时间: { this.state.date.toLocaleTimeString() }</h2>
      }
    }
    
    ReactDOM.render(
      <Clock />,
      document.getElementById('js-main')
    );

    React 通过 diffing 算法计算如何更新视图。而 diffing 算法有个 的假设前提,开发人员会提供给长列表的每个子项一个 ID,帮助算法进行对比。

    function NumberList(props) {
      const numbers = props.numbers;
      const listItems = numbers.map((number) =>
        <li key={number.toString()}>
          {number}
        </li>
      );
      return (
        <ul>{listItems}</ul>
      );
    }
    
    const numbers = [1, 2, 3, 4, 5];
    ReactDOM.render(
      <NumberList numbers={numbers} />,
      document.getElementById('root')
    );

    完成的渲染流程

    初始化的渲染流程分为 3 步。

    第一步,开发者使用 JSX 语法写 React,babel 会将 JSX 编译为浏览器能识别的 React JS 语法。这一步,一般配合 webpack 在本地进行。

    第二步,执行 ReactDOM.render 函数,渲染出虚拟DOM。

    第三步,react 将虚拟DOM,渲染成真实的DOM。

    页面更新的流程同样也是 3 步。

    第一步,当页面需要更新时,通过声明式的方法,调用 setState 告诉 react。

    第二步,react 自动调用组件的 render 方法,渲染出虚拟 DOM。

    第三步,react 会通过 diffing 算法,对比当前虚拟 DOM 和需要更新的虚拟 DOM 有什么区别。然后重新渲染区别部分的真实 DOM。

    原文:https://segmentfault.com/a/1190000007463108#articleHeader0

  • 相关阅读:
    UVA12125 March of the Penguins (最大流+拆点)
    UVA 1317 Concert Hall Scheduling(最小费用最大流)
    UVA10249 The Grand Dinner(最大流)
    UVA1349 Optimal Bus Route Design(KM最佳完美匹配)
    UVA1212 Duopoly(最大流最小割)
    UVA1395 Slim Span(kruskal)
    UVA1045 The Great Wall Game(二分图最佳匹配)
    UVA12168 Cat vs. Dog( 二分图最大独立集)
    hdu3488Tour(KM最佳完美匹配)
    UVA1345 Jamie's Contact Groups(最大流+二分)
  • 原文地址:https://www.cnblogs.com/showcase/p/10577563.html
Copyright © 2011-2022 走看看