zoukankan      html  css  js  c++  java
  • react(三)

    深入 JSX

    从本质上讲,JSX 只是为 React.createElement(component, props, ...children) 函数提供的语法糖。

    // JSX代码:
    <MyButton color="blue" shadowSize={2}>Click Me</MyButton>
    // 编译为:
    React.createElement(
      MyButton,
      {color: 'blue', shadowSize: 2},
      'Click Me'
    )

    如果不存在子节点,你可以使用自闭合(self-closing)格式的标签。

    // JSX代码:
    <div className="sidebar" />
    // 编译为:
    React.createElement(
      'div',
      {className: 'sidebar'},
      null
    )
    ReactDOM.render(
      // <div className='sidebar' />,
      React.createElement(
        'div',
        {className: 'sidebar'},
        null
      ),
      document.getElementById('container')
    );

    a)指定 React 元素类型

    一个 JSX 标签的开始部分决定了 React 元素的类型,首字母大写的标签指示 JSX 标签是一个 React 组件,这些标签会被编译成 命名变量 的直接引用。所以如果你使用 JSX <Foo /> 表达式,那么 Foo 必须在作用域中

    React 必须在作用域中。因为 JSX 被编译为 React.createElement 的调用,所以 React 库必须在你 JSX 代码的作用域中

    例如,所有的 imports 在这段代码中都是必须的。如果你不使用 JavaScript 打包器,而是通过在 <script> 标签加载 React ,它已经作为一个全局 React 存在。

    import React from 'react';
    import CustomButton from './CustomButton';
    function WarningButton() {
      // return React.createElement(CustomButton, {color: 'red'}, null);
      return <CustomButton color="red" />;
    }

    b)对 JSX 类型使用点语法

    在 JSX 中,你也可以使用点语法引用一个 React 组件。如果你有一个单一模块(module) ,但却导出(exports) 多个 React 组件时,这将会很方便。例如,如果 MyComponents.DatePicker 是一个组件,你可以直接在 JSX 中使用它:

    const MyComponents = {
      DatePicker(props) {
        return <div>Imagine a {props.color} datepicker here.</div>;
      }
    }
    function BlueDatePicker() {
      return <MyComponents.DatePicker color="blue" />;
    }

    c)用户定义组件必须以大写字母开头

    当一个元素类型以小写字母开头,它表示引用一个类似于 <div> 或者 <span> 的内置组件,会给 React.createElement 方法传递 'div' 或者 'span' 字符串。以大写字母开头的类型,类似于 <Foo />,会被编译成 React.createElement(Foo) ,对应于自定义组件或者在 JavaScript 文件中导入的组件。

    d)JSX 中的 props(属性)

    props(属性) 默认为 “true”

    如果你没给 prop(属性) 传值,那么他默认为 true 。下面两个 JSX 表达式是等价的:

    <MyTextBox autocomplete />
    <MyTextBox autocomplete={true} />

    通常情况下,我们不建议使用这种类型,因为这会与ES6中的对象shorthand混淆 。ES6 shorthand 中 {foo} 指的是 {foo: foo} 的简写,而不是 {foo: true} 。这种行为只是为了与 HTML 的行为相匹配。(举个例子,在 HTML 中,<input type="radio" value="1" disabled /> 与 <input type="radio" value="1" disabled="true" /> 是等价的)

    e)jsx中的children 

    class App extends React.Component {
        render() {
            return (
            <div>
                <h1>{this.props.title}</h1>
                {this.props.children}
    </div>
            );
        }
    }
    
    ReactDOM.render(
      <App title="编辑供应商">
          <div className="supply">供应商Id: 123</div>
      </App>,
      document.getElementById('root')
    );

    浏览器渲染结果:

      

    使用 PropTypes 进行类型检查

    随着应用日渐庞大,你可以通过类型检查捕获大量错误。 要检查组件的属性,你需要配置特殊的 propTypes属性。PropTypes 包含一整套验证器,可用于确保你接收的数据是有效的。

    import PropTypes from 'prop-types';
    class Greeting extends React.Component {
      render() {
        return (
          <h1>Hello, {this.props.name}</h1>
        );
      }
    }
    Greeting.propTypes = {
      name: PropTypes.string
    };

    在这个示例中,我们使用了 PropTypes.string。当你给属性传递了无效值时,JavsScript 控制台将会打印警告。出于性能原因,propTypes 只在开发模式下进行检查

    Refs 和 DOM

    不要过度使用 Refs:你可能首先会想到在你的应用程序中使用 refs 来更新组件。如果是这种情况,请花一点时间,更多的关注在组件层中使用 state。在组件层中,通常较高级别的 state 更为清晰。

    在 DOM 元素上添加 Ref:React 支持给任何组件添加特殊属性。ref 属性接受回调函数,并且当组件 装载(mounted) 或者 卸载(unmounted) 之后,回调函数会立即执行。当给 HTML 元素添加 ref 属性时, ref 回调接受底层的 DOM 元素作为参数

    class CustomTextInput extends React.Component {
      constructor(props) {
        super(props);
        this.focus = this.focus.bind(this);
      }
      focus() {
        // 通过使用原生API,显式地聚焦text输入框
        this.textInput.focus();
      }
      render() {
        // 在实例中通过使用`ref`回调函数来存储text输入框的DOM元素引用(例如:this.textInput)
        return (
          <div>
            <input type="text" ref={(input) => { this.textInput = input; }} />
            <input type="button" value="Focus the text input" onClick={this.focus} />
          </div>
        );
      }
    }
    ReactDOM.render(
      <CustomTextInput />,
      document.getElementById('container')
    );

     

    优化性能

    使用生产版本:如果你在你的 React 应用程序中进行检测性能问题时,确保你正在使用压缩过的生产版本。默认情况下,React包含很多在开发过程中很有帮助的警告。然而,这会导致 React 更大更慢。因此,在部署应用时,请确认使用了生产版本

    最好在开发应用时使用开发模式,部署应用时换为生产模式。我们提供压缩好的生产版本的 React 和 React DOM 文件(注意只有结尾为 .min.js 的React文件才是适合生产使用的)。

    <script src="https://unpkg.com/react@15/dist/react.min.js"></script>
    <script src="https://unpkg.com/react-dom@15/dist/react-dom.min.js"></script>

    避免重新渲染:React 构建并维护渲染 UI 的内部表示。它包括你从组件中返回的 React 元素。这些内部状态使得 React 只有在必要的情况下才会创建DOM节点和访问存在DOM节点,因为对 JavaScript 对象的操作是比 DOM 操作更快。这被称为”虚拟DOM”。当组件的 props 和 state 改变时,React 通过比较新返回的元素 和 之前渲染的元素 来决定是否有必要更新DOM元素。当二者不相等时,则更新 DOM 元素。

    React 顶层 API

    React 是 React 库的入口。如果你用 <script> 标签来加载 React,这些顶级 API 都在 React 这个全局变量上。如果你在 npm 下使用 ES6 ,你可以这样写 import React from 'react' 。如果你在 npm 下使用 ES5,你可以这样写 var React = require('react') 。

    React 组件允许你将UI拆分为独立的可重用的模块,并且每个模块逻辑也是独立的。 React组件可以通过扩展 React.Component 或 React.PureComponent 来定义

    React.Component 是 React 组件使用 ES6 类(classes) 定义时的基类

    每个组件都有几个 “生命周期方法” ,前缀为 will 的方法在一些事情发生之前被调用,而前缀为did的方法在一些事情发生后被调用。

    constructor(props)

      在 React 组件被装载(mounted)前,该组件的 constructor(构造函数) 将被调用。当实现 React.Component 子类的 constructor(构造函数) 方法时,你应该在其它任何其他语句之前调用 super(props) ,否则,this.props 将在 constructor(构造函数) 中是 undefined(未定义) ,这将导致 bug 。构造函数是初始化 状态(state) 的正确位置。 为此,只需将一个对象分配给this.state ; 不要尝试在构造函数上调用 setState() 。 构造函数也经常用于将事件处理程序绑定到类实例。如果你没有初始化 状态(state) ,并且没有绑定方法,你不需要为你的 React 组件实现一个构造函数。

    render()

    render()方法是必需的。当被调用时,它会检查 this.props 和 this.state 并返回一个单独的 React 元素。 此元素可以是原生 DOM 组件的表示形式,例如 <div /> ,也可以是你自己定义的另一个复合组件。

    componentDidMount()

    componentDidMount() 在组件 装载(mounting) 后被立即调用。初始化所需要的 DOM 节点的应该放在这里。 如果你需要从远程加载数据,这是一个实例化网络请求的好地方。

    componentWillUnmount()

    componentWillUnmount() 在一个组件被 卸载(unmounted) 和 销毁(destroyed) 之前立即被调用。 在此方法中执行任何必要的清理,例如使计时器无效,取消网络请求,或清理在 componentDidMount 中创建的任何 DOM 元素。

    setState(updater, [callback])

    setState() 排队更改组件的 state ,并通过更新 state 来告诉 React ,该组件及其子组件需要重新渲染。这是用于 响应事件处理程序 和 服务器响应 更新用户界面的主要方法。setState() 总是会导致重新渲染,除非 shouldComponentUpdate() 返回 false 。

    第一个参数可以是一个 updater 函数,您也可以随意的传递 一个对象 作为 setState() 的第一个参数。

    ReactDOM

    如果使用 <script> 标签加载 React ,这些在 ReactDOM 上的顶层 API 全局可用。 如果你使用 ES6 与 npm ,你可以写 import ReactDOM from 'react-dom'。如果你使用 ES5 与 npm ,你可以写 var ReactDOM = require('react-dom') 。

    React支持所有流行的浏览器,包括 Internet Explorer 9 及更高版本。

    ReactDOM.render(
      element,
      container,
      [callback]
    )

    渲染一个 React 元素到由 container 提供的 DOM 中,并且返回组件的一个 引用(reference)(或者对于 无状态组件 返回 null )。如果 React 元素先前已经被渲染到了 container 中,那么将对其执行更新,并且对 DOM 只修改需要修改的地方,以反映最新的 React元素ReactDOM.render() 控制传入的容器节点的内容。当第一次调用时,容器内部的任何现有DOM元素都会被替换。 之后使用 React 的 DOM diffing 算法来进行有效的更新。ReactDOM.render() 不会修改容器节点(只修改容器的子节点)。

    DOM 元素

    在 React 中,所有 DOM properties 和 attributes(包括事件处理程序)都应该是驼峰命名法命名。 例如,HTML 属性 tabindex 对应于 React 中的 tabIndex 属性。 唯一的例外是 aria-*和 data-* 属性,它们应该是小写。例如,aria-label 就应该是 aria-label,不需要驼峰式命名。

    属性中的差异 - 有许多属性在 React 和 HTML 之间有不同的使用方式,如:

    className:一般要指定 CSS 类,使用 className 属性。 这适用于所有常规DOM和SVG元素,如 <div> ,<a> 和其他。

    style(一般不建议在元素上应用 style 属性。在大多数情况下,应该使用 className 引用外部 CSS 样式表中定义的类。 在 React 应用程序中,经常在渲染时使用 style 来添加动态计算的样式):style 属性接受具有驼峰命名属性的 JavaScript 对象,而不是 CSS 字符串。 这与 JavaScript DOM 的 style 属性一致,但是更高效,并且防止XSS安全漏洞。ms 以外的供应商前缀应以大写字母开头。

    <form style={{backgroundColor:'#fff',fontSize:'14px'}} className="search-form"></form>

    浏览器渲染结果:

    const divStyle = {
      WebkitTransition: 'all', // 注意这里的大写首字母 'W'
      msTransition: 'all' // 'ms' 'ms'是唯一的小写字母的浏览器前缀,大小写均可
    };
    function ComponentWithTransition() {
      return <div style={divStyle}>This should work cross-browser</div>;
    }
  • 相关阅读:
    理解“统一编址与独立编址、I/O端口与I/O内存” arm
    JS + CSS 美化 select 下拉框表单
    关于 ecshop common.js 文件 自动随机输出 Powered by ECShop
    Zend Framework 入门随笔 配置与注意事项
    Delphi编程保存数据到Excel文件(4):使用NativeExcel2控件
    ORACLE 最大连接数的问题1
    一生delphi编程经验(转)
    XLSReadWriteII控件来完成10×10的乘法表
    Delphi 动态调整打印机纸张大小
    Linux下Oracle重启和修改连接数3
  • 原文地址:https://www.cnblogs.com/colorful-coco/p/9257946.html
Copyright © 2011-2022 走看看