Giter Site home page Giter Site logo

jianshu's People

Contributors

wenshaofeng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

jianshu's Issues

React 事件绑定中的 `this`

React 中关于事件绑定的 this

为什么要绑定 this

let obj = {
  tmp: 'Yes!',
  testLog: function () {
   console.log(this.tmp);
   }
};
// obj.testLog();
 let tmpLog = obj.testLog
 tmpLog()

  /*  在上面的例子里,当我们调用 tmpLog() 时,
我们没有指定一个具体的上下文对象。这是一个没有所有者对象的纯函数调用。
 在这种情况下,tmpLog() 内部的 this 值回退到默认绑定。
 现在这个 this 指向全局对象,在严格模式下,它指向 undefined。 */
        class Foo {
            constructor(name) {
                this.name = name
            }

            display() {
                console.log(this.name);
            }
        }

        var foo = new Foo('Saurabh');
        foo.display(); // Saurabh

        //下面的赋值操作模拟了上下文的丢失。 
        //与实际在 React Component 中将处理程序作为 callback 参数传递相似。
        var display = foo.display;
        display(); // TypeError: this is undefined

类声明类表达式的主体以 严格模式 执行,主要包括构造函数、静态方法和原型方法。Getter 和 setter 函数也在严格模式下执行。所以 在React 中 ,由于大多数情况下创建组件会用 Class 继承 Component,所以 this 处于 严格模式 下,不会指向全局对象 ,而是 undefined

事件处理程序方法会丢失其隐式绑定的上下文。当事件被触发并且处理程序被调用时,this的值会回退到默认绑定,即值为 undefined,这是因为类声明和原型方法是以严格模式运行。
当我们将事件处理程序的 this 绑定到构造函数中的组件实例时,我们可以将它作为回调传递,而不用担心会丢失它的上下文。
箭头函数可以免除这种行为,因为它使用的是词法 this 绑定,会将其自动绑定到定义他们的函数上下文。

绑定this的几种方式

  • (1)直接 bind (不太合适,每次渲染(执行render函数)都要绑定一次)
class Home extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
        };
    }

    del(){
        console.log('del')
    }

    render() {
        return (
            <div className="home">
                <span onClick={this.del.bind(this)}></span>
            </div>
        );
    }
}
  • (2)在构造函数 constructor 内绑定this
    仅需要绑定一次,避免每次渲染时都要重新绑定,函数在别处复用时也无需再次绑定
class Home extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
        };
        this.del = this.del.bind(this)
    }

    del(){
        console.log('del')
    }

    render() {
        return (
            <div className="home">
                <span onClick={this.del}></span>
            </div>
        );
    }
}
  • (3)箭头函数绑定
class Home extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
        };
    }

 del=()=>{
        console.log('del')
    }


    render() {
        return (
            <div className="home">
                <span onClick={this.del}></span>
            </div>
        );
    }
}

参考文章
[译] 为什么需要在 React 类组件中为事件处理程序绑定 this

JSX 语法

JSX语法

从本质上讲,JSX 只是为 React.createElement(component, props, ...children) 函数提供的语法糖。Babel 转译器会把 JSX 转换成一个名为 React.createElement() 的方法调用。JSX代码:

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

转译为:

React.createElement(
  MyButton,
  {color: 'blue', shadowSize: 2},
  'Click Me'
)

JSX 本身其实也是一种表达式
在编译之后呢,JSX 其实会被转化为普通的 JavaScript 对象。

这也就意味着,你其实可以在 if 或者 for 语句里使用 JSX,将它赋值给变量,当作参数传入,作为返回值都可以:

function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}

render函数是个纯函数,不做任何直接渲染的事情。只是返回了一些指令,由React对这些指令做真正DOM操作。

要记住一点:在React的render函数,不要使用push、reverse这种数组的函数。因为render函数应该是纯函数,它不应该有任何副作用。渲染的东西最后是data,这个data可能是state或者props。如果用了push或者reverse,实际上改的是props或者state,最后产生的结果不可预料,因为你不是纯函数。

// JSX
<button type="submit">
    Save
</button>

注意JSX可以包含花括号,花括号里面最后都是一个JavaScript表达式,实际上都是createElement的某个参数。正因为它是参数,所以它必须是表达式,它不能是语句。故不可能有for、while循环,因为二者一出现,就表示这是语句,不是表达式。

  • 组件写样式,不要直接用class,会和es6关键字同名,得用 className
  • 组件属性:dangerousSetInnerHTML 危险的转换html

JSX是进步还是倒退

在HTML中的 onclick 缺点

  • onclick添加的事件处理函数是在全局环境下执行的,污染了全局环境
  • 如果给多个DOM元素添加 click 事件,会影响网页性能,因为网页需要的事件处理函数越多,性能就会降低
  • 使用 click 的DOM元素,如果需要动态的删除,需要注销 时间处理器,否则可能造成内存泄露

而 React 中的 onClick ,是使用了事件委托的方式处理点击事件,无论有多少个onClick出现, 其实最后都只在DOM树上添加了一个事件处理函数, 挂在最顶层的DOM节点上。 所有的点击事件都被这个事件处理函数捕获, 然后根据具体组件分配给特定函数。

React 的设计**

React 的设计**

React 始终整体刷新页面,而让我们不需要关心太多细节

React 的基础原则

  1. React 界面完全由数据驱动;
  2. React 中一切都是组件;
  3. props 是 React 组件之间通讯的基本方式。

界面完全由数据驱动

React 的哲学

UI(页面) = f(data) data可以是 state 或者 props

UI 就是把 data 作为参数传递给 f 运算出来的结果。这个公式的含义就是,如果要渲染界面,不要直接去操纵 DOM 元素,而是修改数据,由数据去驱动 React 来修改界面。

我们开发者要做的,就是设计出合理的数据模型,让我们的代码完全根据数据来描述界面应该画成什么样子,而不必纠结如何去操作浏览器中的 DOM 树结构。

这样一种程序结构,是声明式编程(Declarative Programming)的方式,代码结构会更加容易理解和维护。

组件:React 世界的一等公民

可以这么说,在 React 中一切皆为组件。这是因为:

  1. 用户界面就是组件;
  2. 组件可以嵌套包装组成复杂功能;
  3. 组件可以用来实现副作用。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.