https://reactjs.org/docs/higher-order-components.htmlhttps://codepen.io/gaearon/pen/WooRWa?editors=0010

JSX in Depth

https://babeljs.io/  JS编译器,学习react和JS直接的转换。

JSX仅支持句法糖syntactic sugar:

React.createElement(component, props, ...children)函数,

JSX code:

<MyButton color="blue" shadowSize={2}>
Click Me
</MyButton>
 

编译compiles into:

React.createElement(

  MyButton,
  {color: 'blue', shadowSize: 2},
  'Click Me'
)   

也可以使用self_closing form of the tag if there are no children. So:

<div className="sidebar" />

compiles into:

React.createElement(
  'div',
  {className: 'sidebar'},
  null
)

函数形式的:

function hello() {

return <div>Hello world!</div>;

}

转换为:

function hello() {
  return React.createElement(
    'div',
    null,
    'Hello world!'
  );
}

关于React元素的格式:

React 一定在Scope内。

使用. Dot Notaiton ,可以在JSX中使用点符号。如果一个模块要调出一些React组件,这样就方便了。例子:

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

自定义的组件必须首字母大写(除非分配它一个首字母大写的变量)。function Hello(props){...}

在运行时选择类型Choosing the type at runtime

不能把表达式用做React element type。但是可以把它分配给一个大写字母的变量,然后就可以间接用JSX格式了

import React from 'react';
import { PhotoStory, VideoStory } from './stories';
const components = {
  photo: PhotoStory,
  video: VideoStory
};
function Story(props) {
  // Wrong! JSX type can't be an expression.
  return <components[props.storyType] story={props.story} />;
}
function Story(props) {
  // Correct! JSX type can be a capitalized variable.
  const SpecificStory = components[props.storyType];
  return <SpecificStory story={props.story} />;
}

Props in JSX

通过{}, 任何JS expression 都可以作为props. 例如<MyComponent foo={1 + 2 + 3 + 4} />

if statements and for loops 不是JS表达式,不能直接用于JSX。但{}就能用了

function NumberDescriber(props) {
  let description;
  if (props.number % 2 == 0) {
    description = <strong>even</strong>;
      } else {
        description = <i>odd</i>
      }
  return <div>{props.number} is an {description} number</div>;
}

条件判断 Inline的写法:

{true && expression}  //如果是true,则执行表达式。

{condition ? true : false }

防止组件被渲染:

return null; ⚠️,组件的lifecycle 方法钩子方法,仍然生效componentWillUpdate 和 componentDidUpdate。


Children in JSX

string Literals

<div>This is valid HTML &amp; JSX at the same time.</div>

&amp; 就是&

编译:

React.createElement(
  "div",
  null,
  "This is valid HTML & JSX at the same time."
);

JSX移除一行开头和结尾的空格

JSX Children

支持内嵌JSX元素作为孩子。在嵌套组件中很有用。

React组件也返回数组元素。return [, ,];

JS expression也可以作为孩子。

function Item(props) {
  return <li>hello, {props.message}</li>;  //props.children
}
function TodoList() {
  const todos = ['finish', 'submit ', 'review'];
  return (
    <ul>

//这个是函数作为props.children。

      {todos.map(message =>
        <Item key={message} message={message} />
      )} 
    </ul>
  );
}

Function as Children

见标黄的代码.React.createElement(component, props,...child)

function Repeat(props) {
  let items = [];
  for (let i= 0; i < props.numTimes; i++) {
    items.push(props.children(i));
  }
  return <div>{items}</div>;
}
function ListOfTenThings() {
  return (
    <Repeat numTimes={10}>
      {(index) => <div key={index}>{index}:This is item {index}</div>}
    </Repeat>
  );
}

Booleans, Null, and Undefined are Ignored.

false ,null, undefined, true都是验证的孩子,不过它们不渲染。

所以可以作为条件判断 condition && expression。

如果showHeader是true则渲染<Header />

<div>
  {showHeader && <Header />}
  <Content />
</div>

⚠️ 0会被渲染

如果要让true渲染使用类型转换,String()。


Typechecking With PropTypes(未看)

用于检查输入的一个方法PropTypes ,这是React内置的方法,JS扩展中也有Flow,TypeScript等扩展插件。

大型的代码检查,官方推荐使用Flow or TypeScript 而不是用默认的。

https://reactjs.org/docs/typechecking-with-proptypes.html

PropTypes输出了一组验证器用于确保你接收的数据是通过验证的。如果一个未通过验证的值提供给一个prop,一条warning会显示在JS console中。propTypes只用于开发模式。

import PropTypes from 'prop-types';
class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}</h1>
    );
  }
}
Greeting.propTypes = {
  name: PropTypes.string    //确保是string类的值,否则报告⚠️信息。
};

Refs ans the DOM(未看)

https://reactjs.org/docs/refs-and-the-dom.html

在典型的数据流模式,组件之间的交互使用props。但有少数情况属于例外情况。

Refs提供了一个方法,能够使用DOM nodes 和React elements created in the render method。React提供了这个escape hatch逃生舱门。

何时用:

  • 管理focus,text selection ,media playback
  • 合并第三方DOM库
  • 打开必要的动画Triggering imperative animations
React.createRef:

创建一个ref可以附加到React elements

this.myRef = React.createRef() 并通过ref属性付给React元素


Uncontrolled Components

推荐使用controlled components 来实现forms, 这时,表格数据被React组件处理。

但我们也可以用别的方式,这时,表格data被DOM自身处理。

既然非控制组件保持了DOM的原生性,有时它比较容易合并React和非React代码。如果你想要更快并不在乎代码太脏(可读性差),也能够稍微少输入点代码。

你应该尽量用可控制的组件。

https://codepen.io/gaearon/pen/WooRWa?editors=0010

红字是用原生DOM加ref。

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleTextChange = this.handleTextChange.bind(this);
    this.state = {text: ""};
  }
  
  handleTextChange(e) {
    this.setState({text: e.target.value});
  }
  
  handleSubmit(e) {
    // alert("A name was submitted: " + this.input.value);
    alert("A name was submitted: " +  this.state.text);
    e.preventDefault();
  }
  
  render() {
    return (
      // <form onSubmit={this.handleSubmit}>
      //   <label>
      //     Name:
      //     <input type="text" ref={(input) => this.input = input}  />
      //   </label>
      //   <input type="submit" value="Submit" />
      // </form>
      <form>
        <label>
          Name:
          <input type="text" onChange={this.handleTextChange}/>
        </label>
        <input type="submit" value="Submit" onClick={this.handleSubmit} />
      </form>
    );
  }
}
ReactDOM.render(
  <NameForm />,
  document.getElementById('example')
);

Optimizing Performance(略读)

优化执行的方法和工具。

使用React Developer Tools for Chrome.(也有其他浏览器版本)

这个工具可以制作Timeline可视化每个组件mount update, unmount.


Context(一个不使用传统方法传递数据的方法。)

https://reactjs.org/docs/context.html

一整章节,暂时不看。


Fragments

让你返回多个元素在一个render()方法中,不需要创建一个额外的DOM 元素。

The React.Fragment component lets you return multiple elements in a render()method without creating an additional DOM element:

render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

这时如果是静态的可以不加key,最好加上。另外用[]也可以,但必须加key

HTML description list:

<dl>

<dt>

<dd></dd>

</dt>

</dl>


Portals

大门,入口。

https://reactjs.org/docs/portals.html

渲染孩子进入一个Dom节点

ReactDOM.createPortal(child,container)

第一个参数是任意的渲染的React child。如an element, string, or fragment.

第二个参数container是一个DOM元素。

一般来说,从一个组件的渲染方法中返回一个元素,它作为孩子附加在离它最近的父节点后。

而使用createPortal这样就可以插入一个孩子到DOM中不同的位置。 (但仍然受到父组件event事件的影响)

案例:https://codepen.io/gaearon/pen/yzMaBd?editors

    return (
      <div className="app">
        This div has overflow: hidden.
        <button onClick={this.handleShow}>Show modal</button>
        {modal}  //看似是在这个block中,其实Modal组件使用了createProtal()把自己插入到了其他DOM节点。
      </div>
    );

Event Bubbling Through Portals

a portal可以插入到在DOM tree的任何位置,不过它在其他方面仍旧是一个普通的React child。

假如:在一个父组件中渲染一个子组件(Modal),那么Modal就可以被这个父组件捕捉到。这个父组件不会考虑Modal是否用了protals。

即便Modal用了protal把代码插入到不属于父组件的其他节点,父组件仍然可以捕捉到Modal,父组件定义了一个点击事件,对Modal中的元素进行点击也会触发父组件的点击事件。

案例:https://codepen.io/chentianwei411/pen/ZoLeBE?editors=0010


Error Boundaries

错误边界。 目的:解决仅仅是部分UI的错误就会造成整个app崩溃的问题。

Error boundaries也是一个React组件。JS 错误发生在子组件的任何位置,它都可以捕捉到,并且log those errors, 并且display a fallback UI。

Error boundaries 捕捉错误是在渲染的时候,因此lifecycle methods 和 constructors of the whole tree都低于Error boundaries.

⚠️以下超出了Error-b的使用范围:

Event handlers, 异步代码, 服务器端渲染, 自身抛出错误。


Higher-Order Components (基本用法,一些约定没有看。)

一种代码的抽象化, 根据dry原则,把有相同逻辑的组件重构。

即重构一个函数,这个函数接受一个组件并return 一个新组件。

要点:发现有很多相同逻辑(内部代码基本一样)的组件, 为了减少代码的量和便于阅读维护。

https://reactjs.org/docs/higher-order-components.html

// 调用Highter-Order组件withSubscription.把返回的新组件存入一个JSX.

const CommentListWithSubscription = withSubscription(

CommentList,

(DataSource) => DataSource.getComments()

);

const BlogPostWithSubscription = withSubscription(
  BlogPost,
  (DataSource, props) => DataSource.getBlogPost(props.id)
);

function withSubscription(WrappedComponent,  selectData) {

//WrappedComponent是组件名字, selectData是数据及其使用的methods。

return class extends React.Component {...} ;  //class后面没有组件名字

}

⚠️ ,不要在higher-order组件中对原有组件修改,如果需要组件进行功能的变化,把这个变化写在return中。

⚠️, 约定convension: 传递不相关的props,通过wrapped 组件。 在render方法中使用不相关的props.


Render Props

术语render prop是一个简单的技术:在React组件之间,通过使用一个值是函数的prop来分享代码。

The term "render prop" refers to a simple technique for sharing code between React components using a prop whose value is a function.

<DataProvider render={data => (
  <h1>Hello {data.target}</h1>
)}/>

一个组件带着一个render prop,这个组件渲染的时候可以使用这个render prop的值

a render prop is a function prop that a component uses to know what to render.

https://reactjs.org/docs/render-props.html



React.Component

组件的lifecycle methods

Methods prefixed with will are called right before sth happens. did are called after sth happens.

Mounting

这些方法在一个组件实例被创建和插入DOM时调用。

constructor(props){...}   //在加载组件前调用。

before it is mounted,如果组件是一个子类,还需要在其他声明前面调用super(props)。 constructor()用于初始化state。也用于bind event-handlers to the class instance.

分配给this.state的对象可以包含props。但⚠️这不是时时更新的,最好不这么用,例子:

  this.state = {
    color: props.initialColor
  };

UNSAFE_componentWillMount()   //在加载组件前引用。它在render()前调用。

render()

When called, it should examine this.props and this.state and return one of the following types:

  • React elements. 包括自定义的组件或原生的DOM component <div />
  • String and numbers. 作为text nodes 渲染在DOM中。
  • Portals. Created with ReactDOM.createPortal
  • null 什么也不加载
  • Booleans。一般用于 return test && <Child />模式,当test是true时,加载后面
⚠️ shouldComponentUpdate()方法返回false时,不加载render()

componentDidMount()   //在组件加载后立即引用

用途:

加载远程endpoint的数据,这里可以实例化network request。

也可以建立任何订阅并配合componentWillUnmount()取消订阅。

调用setState(),会激活额外的rendering.

Updating

一个update会被props或state的改变引起。下面的方法当一个组件被再加载时调用。(只看了其中几个,一共7个方法)

componentWillReceiveProps()

在一个已经加载的组件再次接收新的props之前引用这个方法。 这个方法限制很多不推荐用。

shouldComponentUpdate(nextProps, nextState)

返回true,false。让React知道一个组件的输出是否被当前state or propsde 变化所影响。如果是true,则组件再render()。方法默认是true。所以一般不主动使用这个方法。

如果是false,render(), componentWillUpdate(), componentDidUpdate()不会调用。

componentWillUpdate(nextProps, nextSate)

当一个新props or state 被接收到后,在渲染之前引用。

render()

每次更新props or state后,调用render().

componentDidUpdate(prevProps, prevState, snapshot)

在更新发生后,立即引用。

Unmounting

  • componentWillUnmount(): 在一个组件被卸载和删除前立即引用。用于执行必要的清洁。如未验证的timers, 取消网络请求, 清洁任何在componentDidMount()中的订阅
Error Handing
  • componentDidCatch():这个方法被调用当一个❌发生在渲染中,在lifecyle方法中,或者在一个孩子组件的constructor中。

Other APIS

setState()

enqueuqs changes to the component state and tells React that this component and its children need to be re-rendered with the updated state.

改变组件的状态state并告诉React“组件和它的孩子需要根据更新的state再渲染”

这是一个主要的方法,用来更新user interface in response,事件处理和服务器响应。

把setState()当作一个request,而不是更新组件的即时命令。

setState()不总是立即执行更新组件,因为它类似request,有延迟。因此,使用componentDidUpdate或者setState(updater, callback)可以保证fire(立即执行).

setState(updater, callback)

updater是一个函数:(prevState, props) => stateChange   //prevState是之前state的一个引用。 例子:用props.step增加一个值到state中。

this.setState((prevState, props) => {
  return {counter: prevState.counter + props.step};
}); 

callback参数是可选的函数。在setState完成更新,组件被再渲染后执行这个函数,推荐使用componentDidUpdate代替。

第一个参数可以是一个对象object.代替一个函数。 这个执行会把状态变化合并到新状态中。

this.setState({quantity: 2})

forceUpdate()

component.forceUpdate(callback),如果render()方法依靠其他数据源,你可以告诉组件调用forceUpdate()来再渲染。个人理解:这个方法就是用来执行渲染的。

Class Properties

defaultProps

给组件的property设定默认值。

class CustomButton extends React.Component {
  // ...
}
CustomButton.defaultProps = {
  color: 'blue'
};

渲染的时候自动增加上color="blue"

render() {
  return <CustomButton /> ; // props.color will be set to blue
}

displayName

https://reactjs.org/docs/higher-order-components.html#convention-wrap-the-display-name-for-easy-debugging

debug用。

Instance Properties

  • props
  • state


ReactDOM

import ReactDOM from 'react-dom'

react-dom package提供了DOM-specific methods。大多数组件不需要使用这个module.

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

渲染一个React element到DOM中。具体位置是container, 返回a reference 给组件。

如果之前已经渲染进container中,更新时只修改必要的部分。

callback可选,在组件渲染或更新后执行.\

createPoratal()

ReactDOM.createPortal(child, container)

hydrate()
unmountComponentAtNode()
findDOMNode()


ReactDOMServe

import ReactDOMServer from 'react-dom/server';

用于把组件渲染到静态标记中,一般用于一个Node server

这两个方法可以用于server,也可以用在浏览器。

renderToString()

renderToStaticMarkup()

ReactDOMServer.renderToString(element)

渲染一个React元素到 原始HTml. React返回一个HTML string。


DOM Elements

https://reactjs.org/docs/dom-elements.html

style

style属性可以接受JS 对象。属性要用驼峰写法。如backgroundImage. px可以省略

const divStyle = {
  color: 'blue',
  background: 'lightblue',
};
function Hello() {
  return <div style={divStyle}>Hello World!</div>;
}

value

<input>, <textarea>组件支持value属性。

className

用来指定css class的名字。

checked

<input>组件中的type类型为checkbox or radio的支持这个属性。

All Supported HTML Attributes


SyntheticEvent

人工事件

event handlers被传到人工事件的实例,一个跨浏览器的包裹器(包含浏览器的原生事件)。

每个SyntheticEvent对象有一系列的属性attributes:如:

currentTarget, target, type, timeStamp, isTrusted, preventDefault()等等。

https://reactjs.org/docs/events.html

JavaScript 和 React,React用了大量语法糖,让JS编写更方便。的更多相关文章

  1. JavaScript中if语句优化和部分语法糖小技巧推荐

    前言 在前端日常开发过程中,if else判断语句使用的次数应该是比较频繁的了,一些较为复杂的场景,可能会用到很多判断,在某个代码块使用很多if else时,代码会显得较为冗余,阅读起来不够清晰. 除 ...

  2. React: React组件创建的三种方式

    一.简介 在前面介绍的React组件知识中,对于组件的创建我只是用了其中某一种方式.其实,在2013年React诞生之初,对于React组件的创建,仅仅只有一种方式,也即createClass函数,在 ...

  3. 探索C#之6.0语法糖剖析

    阅读目录: 自动属性默认初始化 自动只读属性默认初始化 表达式为主体的函数 表达式为主体的属性(赋值) 静态类导入 Null条件运算符 字符串格式化 索引初始化 异常过滤器when catch和fin ...

  4. C++11新语法糖之尾置返回类型

    C++11的尾置返回类型初衷是为了方便复杂函数的声明和定义,但是当复杂度稍微提升一些的时候很明显能注意到这种设计的作用微乎其微. 首先考虑如下代码: C++ //返回指向数组的指针 auto func ...

  5. C#语法糖(Csharp Syntactic sugar)

    目录 一.C#语法糖大汇总 1. 经过简化的Property2. 经过两次变异的委托写法3. 集合类的声明4. 集合类各个项的操作5. using == try finally6. 可爱的var7. ...

  6. C# 6.0语法糖剖析

    C# 6.0语法糖剖析 2016年12月16日 16:10:27 阅读数:586   版权声明:本文为博主http://www.feixueteam.net原创文章,未经博主允许不得转载. https ...

  7. java语法糖---枚举

    java语法糖---枚举   在JDK5.0中提供了大量的语法糖,例如:自动装箱拆箱.增强for循环.枚举.泛型等.所谓“语法糖”就是指提供更便利的语法供程序员使用,只是在编译器上做了手脚,却没有提供 ...

  8. 从 Vue 的视角学 React(二)—— 基本语法

    基于 Vue.js 开发的时候,每个 vue 文件都是一个单独的组件,可以包含 HTML,JS,CSS 而 React 是以函数为基础,每个 function 就是一个组件.虽然 JSX 让 HTML ...

  9. React笔记_(3)_react语法2

    React笔记_(3)_react语法2 state和refs props就是在render渲染时,向组件内传递的变量,这个传递是单向的,只能继承下来读取. 如何进行双向传递呢? state (状态机 ...

随机推荐

  1. vue-cli使用

    vue-cli 是一个官方发布 vue.js 项目脚手架,使用 vue-cli 可以快速创建 vue 项目,GitHub地址是:https://github.com/vuejs/vue-cli 一.安 ...

  2. bzoj1647 / P1985 [USACO07OPEN]翻转棋

    P1985 [USACO07OPEN]翻转棋 其实我们只要枚举第一行的状态,后面的所有状态都是可以唯一确定的. 用二进制枚举灰常方便 #include<iostream> #include ...

  3. this逃逸

    首先,什么是this逃逸? this逃逸是指类构造函数在返回实例之前,线程便持有该对象的引用. 常发生于在构造函数中启动线程或注册监听器. eg: public class ThisEscape { ...

  4. 20145330 《网络对抗》PC平台逆向破解:注入shellcode 和 Return-to-libc 攻击实验

    20145330 <网络对抗>PC平台逆向破解:注入shellcode 实验步骤 1.用于获取shellcode的C语言代码 2.设置环境 Bof攻击防御技术 需要手动设置环境使注入的sh ...

  5. 权限管理,pymysql模块

    权限管理 权限管理重点 MySQL 默认有个root用户,但是这个用户权限太大,一般只在管理数据库时候才用.如果在项目中要连接 MySQL 数据库,则建议新建一个权限较小的用户来连接. 在 MySQL ...

  6. 主引导记录MBR的结构和作用

    MBR磁盘分区都有一个引导扇区,称为主引导记录,英文简称为MBR.1. MBR的结构MBR扇区位于整个硬盘的第一个扇区:按照C/H/S地址描述,即0柱面〇磁头1扇 区:按照LBA地址描述即0扇区.它是 ...

  7. 《EMCAScript6入门》读书笔记——22.Module的语法

  8. 如何获取xml循环体报文内容

    Xml报文格式如下所示:   <body> <FILENAME></FILENAME> <records>20</records> < ...

  9. ACMG遗传变异分类标准与指南

    2015年,美国权威机构——美国医学遗传学与基因组学学会(ACMG)编写和发布了<ACMG遗传变异分类标准与指南>.为帮助我国医疗工作者和遗传咨询从业者更好地理解ACMG遗传变异分类标准. ...

  10. C++创建虚拟机调用JAVA类

    ZC: 简要摘抄: “ 1.      Object类出创建JVM. 使用Java类之前必须要创建JVM环境.JDK由java.exe来完成.本文有Object类的静态方法BeginJVM来创建,用E ...