视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
回顾Javascript React基础
2020-11-27 21:55:06 责编:小采
文档


前言

React核心的单向数据流、一切皆数据的state、不会改变的props,以及状态提升等等经常使用便不多总结,需要的看官方文档。

JSX

JSX 本质只是为 React.createElement(component, props, ...children)提供的语法糖!

  • 1.React DOM 在渲染之前都被转换成了字符串,它天生自带防止 XSS 攻击的属性。
  • 2.Babel 转译器会把 JSX 转换成一个名为 React.createElement()的方法调用。在线babel编译
  • 以下两段代码等价(许多react的界面设计器通过这个原理,达到元数据转化React元素,实现界面化编程!)
    嵌套就是多个create方法的嵌套。

    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!"
    )
    );
    }

  • 3.JSX中的属性是可以任何 {} 包裹的 JavaScript 表达式作为一个属性值,不能使用if和for。
  • 需要循环和条件渲染可以使用map、三目,或者使用if/for在jsx代码之外!

    //错误的!
    class A extends React.Component {
    render() {
    return <div>{if(){}else{}}</div>;//原来还蒙蔽的不知道为什么错了0.0
    }
    }

    React.Component (组件)

    创建组件的四种方式:

    React.Component 方式

    class Greeting extends React.Component {
    render() {
    return <h1>Hello, {this.props.name}</h1>;
    }
    }

    ES5

    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>
    )
    }

    PureComponet

    大多数情况下, 我们使用PureComponent能够简化我们的代码,并且提高性能,但是PureComponent的自动为我们添加的shouldComponentUpate函数,只是对props和state进行浅比较(shadow comparison),当props或者state本身是嵌套对象或数组等时,浅比较并不能得到预期的结果,这会导致实际的props和state发生了变化,但组件却没有更新的问题。当然还是有解决的方法的,所以建议还是少用。

    事件处理

    事件绑定的四种方法:推荐使用第一第二种。

    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>
    );
    }
    }

    组合 vs 继承

    在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>;
    }
    }

    不使用 ES6

  • Component || create
  • defaultProps || getDefaultProps
  • constructor state || getInitialState
  • this bind || 不需要
  • 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>;
    }
    });

    Refs

    1.如果可以通过声明式实现,则尽量避免使用 refs。

    2.不能在函数式组件上使用 ref 属性,因为它们没有实例

    3.旧版 API:String 类型的 Refs,存在问题,可能会在未来移除,不推荐使用。

    4.对父组件暴露refs,在父元素拿子元素

    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}
    />
    );
    }
    }
    

    ReactDOM

    获取一个DOM除了refs还有更加简单粗暴的方法findDOMNode。

    findDOMNode 是用于操作底层DOM节点的备用方案。使用它的优先级比refs更低!!

    findDOMNode 只对挂载过的组件有效。

    findDOMNode 不能用于函数式的组件中。

    import ReactDOM from 'react-dom';
    ReactDOM.render(
    element,
    container,
    [callback]//不为人知的第三个参数!!
    )
    ReactDOM.unmountComponentAtNode(container)
    ReactDOM.findDOMNode(component)

    不常用的新发现

  • 空的 JSX 标签Fragments <></>或者<React.Fragment></React.Fragment>
  • 与运算符 && true && expression 总是返回 expression,而 false && expression 总是返回 false。
  • 阻止组件渲染常用null组件的 render 方法返回 null 并不会影响该组件生命周期方法的回调。例如,componentWillUpdate 和 componentDidUpdate 依然可以被调用。
  • 下载本文
    显示全文
    专题