从16年夏天初学React,到17年正式投入到工做中使用,直到如今V16.2发版,React发生了巨大的变化,最近在工做中使用时遇到不少基础不是很是清晰,借此再读 React官方文档 【中文】。
React核心的单向数据流、一切皆数据的state、不会改变的props,以及状态提高等等常用便很少总结,须要的看官方文档。html
JSX 本质只是为 React.createElement(component, props, ...children)提供的语法糖!react
如下两段代码等价(许多react的界面设计器经过这个原理,达到元数据转化React元素,实现界面化编程!)
嵌套就是多个create方法的嵌套。express
function hello() { return <div className="red">Hello,<span>world!</span></div>; }
"use strict"; function hello() { return React.createElement( "div", { className: "red" }, "Hello,", React.createElement( "span", null, "world!" ) ); }
须要循环和条件渲染可使用map、三目,或者使用if/for在jsx代码以外!编程
//错误的! class A extends React.Component { render() { return <div>{if(){}else{}}</div>;//原来还蒙蔽的不知道为何错了0.0 } }
建立组件的四种方式:详情对比参见或者react官网数组
class Greeting extends React.Component { render() { return <h1>Hello, {this.props.name}</h1>; } }
var createReactClass = require('create-react-class'); var Greeting = createReactClass({ render: function() { return <h1>Hello, {this.props.name}</h1>; } }); //或者使用react var Greeting = React.create({ render: function() { return <h1>Hello, {this.props.name}</h1>; } });
const Button = ({ day, increment }) => { return ( <div> <button onClick={increment}>Today is {day}</button> </div> ) }
大多数状况下, 咱们使用PureComponent可以简化咱们的代码,而且提升性能,可是PureComponent的自动为咱们添加的shouldComponentUpate函数,只是对props和state进行浅比较(shadow comparison),当props或者state自己是嵌套对象或数组等时,浅比较并不能获得预期的结果,这会致使实际的props和state发生了变化,但组件却没有更新的问题。固然仍是有解决的方法的,因此建议仍是少用。babel
事件绑定的四种方法:推荐使用第一第二种。dom
class Toggle extends React.Component { constructor(props) { {...} //方法一必须在这里绑定 this.handleClick1 = this.handleClick.bind(this); } handleClick1() { this... } //方法二使用【属性初始化器语法】【须要开启babel stage-0以上】 handleClick2=()=> { this... } render() { return ( <div> <button onClick={this.handleClick1}></button> <button onClick={this.handleClick2}></button> //方法三在使用时绑定 <button onClick={this.handleClick1.bind(this)}></button> //方法四在回调函数中使用 箭头函数 /** 渲染的时候都会建立一个不一样的回调函数。在大多数状况下,这没有问题。然而若是这个回调函数做为一个属性值传入低阶组件,这些组件可能会进行额外的从新渲染。咱们一般建议在构造函数中绑定或使用属性初始化器语法来避免这类性能问题。 **/ <button onClick={(e) => this.handleClick1(e)}></button> </div> ); } }
在React中不推荐使用继承,不推荐继承自定义Component。函数
//不推荐使用 class Parent extends React.Component { render() { return <div>...</div>; } } class A extends Parent { render() { return <div>...</div>; } }
//推荐使用 class A extends React.Component { render() { return <Parent>...</Parent>; } }
class Greeting extends React.Component { constructor(props) { super(props); this.state = {count: props.initialCount}; this.handleClick = this.handleClick.bind(this); } handleClick() { alert(this.state.message); } render() { return <h1 onClick={this.handleClick}>Hello, {this.props.name}</h1>; } } Greeting.defaultProps = { name: 'Mary' };
var createReactClass = require('create-react-class'); var Greeting = createReactClass({ getInitialState: function() { return {count: this.props.initialCount}; }, getDefaultProps: function() { return { name: 'Mary' }; }, handleClick: function() { alert(this.state.message); }, render: function() { //组件中的方法会自动绑定至实例,不须要像上面那样加 .bind(this) return <h1 onClick={this.handleClick}>Hello, {this.props.name}</h1>; } });
function CustomTextInput(props) { return ( <div> <input ref={props.inputRef} /> </div> ); } class Parent extends React.Component { //this.inputElement 就是CustomTextInput中的input render() { return ( <CustomTextInput inputRef={el => this.inputElement = el} /> ); } }
获取一个DOM除了refs还有更加简单粗暴的方法findDOMNode
。
findDOMNode 是用于操做底层DOM节点的备用方案。使用它的优先级比refs更低!!
findDOMNode 只对挂载过的组件有效。
findDOMNode 不能用于函数式的组件中。性能
import ReactDOM from 'react-dom'; ReactDOM.render( element, container, [callback]//鲜为人知的第三个参数!! ) ReactDOM.unmountComponentAtNode(container) ReactDOM.findDOMNode(component)
Fragments
<></>
或者<React.Fragment></React.Fragment>
&&
true && expression 老是返回 expression,而 false && expression 老是返回 false。null
组件的 render 方法返回 null 并不会影响该组件生命周期方法的回调。例如,componentWillUpdate 和 componentDidUpdate 依然能够被调用。### 高阶组件HOC 使用高阶组件(HOC)解决交叉问题ui