#React中类组件中关于回调函数的一个问题

在ES6中,类中定义的方法,是放在原型对象的,供实例对象引用。

//创建一个Person类
        class Person {
            constructor(name,age) {
                this.name = name;
                this.age = age;
            }
        }
        class Student extends Person {
            constructor(name,age,grade) {
                super(name,age);
                this.grade = grade;
            }
            study() {
                console.log(this);
            }
        }
        const st = new Student("john", 12, 'sdfjk');
        st.study();
        const x = st.study;
        x();

所以,在st调用study方法时候,输出的是该实例对象,而将st.study方法赋值给x时,再调用x,那么类中定义的方法都是局部严格模式,所以该方法中的this就是undefined。

而将代码改为:

const st = new Student("john", 12, 'sdfjk');
        st.study();
        const x = st.study.bind({name:'Tom',age:18});
        x();

此时,x中的this就是对象{name:"Tom",age:18}了,输出如下:

下面上jsx代码:

class Weather extends React.Component{
            constructor(props){
                super(props);
                this.state={isHot:false};
            }
            render(){
                return <h1 onClick={this.changeWheather}>今天天气很炎热</h1>
            }
            changeWheather(){
                console.log(this);
            }
        }
        ReactDOM.render(<Weather/>,document.getElementById("test"));

点击,发现changeWheather打印的是undefined。

是因为changeWheather是作为onCick的回调,而部是通过实例调用的,是直接调用类中的方法,默认开启了局部的严格模式,当点击时,调用changeWheather方法,而该方法并不是实例调用的,开启严格模式,所以this就是undefined,所以打印的是undefined

而改正的方法,就是通过bind,将类中定义的changeWheather方法中的this改为实例对象。

        class Weather extends React.Component{
            constructor(props){
                super(props);
                this.state={isHot:false};
                this.test=this.nice.bind(this);
            }
            render(){
                return <h1 onClick={this.test}>今天天气很炎热</h1>
            }
            nice(){
                console.log(this);
            }
        }
        ReactDOM.render(<Weather/>,document.getElementById("test"));

上述修改,当点击时,触发test方法,虽然同样也不是实例对象调用的,但test方法中的this就是实例对象,因为在constructor构造器中,已经通过bind,将nice方法中的this变成了实例对象,所以,输出的是实例对象

上述修改只是为了,更明显的说明,实际上可以:

class Weather extends React.Component{
            constructor(props){
                super(props);
                this.state={isHot:false};
                this.changeWheather=this.changeWheather.bind(this);
            }
            render(){
                return <h1 onClick={this.changeWheather}>今天天气很炎热</h1>
            }
            changeWheather(){
                console.log(this);
            }
        }
        ReactDOM.render(<Weather/>,document.getElementById("test"));

可以看到,实例中也有一个changeWheather方法,这里,在赋值给回调函数时候,首先发现了实例的changeWheateher,所以就不会调用原型对象上的changeWheather方法。

精简写法

class Weather extends React.Component{
            //可以去掉构造器
            //直接用赋值语句,给实例增加属性。
            state={isHot:false};
            render(){
                const isHot=this.state.isHot;
                return <h1 onClick={this.changeWheather}>今天天气很{isHot?"炎热":"凉爽"}</h1>
            }
            //自定义方法,要用赋值语句的形式+箭头函数,箭头函数中的this,就会往外寻找this,而由于是赋值语句
            //所以该属性是放在实例上的,而又因为是箭头函数,所以this,外寻,找到了实例,所以,此处里面的this就是实例。
            changeWheather=()=>{
                const isHot=this.state.isHot;
                this.setState({isHot:!isHot});
            }
        }
        ReactDOM.render(<Weather/>,document.getElementById("test"));

关于类中赋值语句+箭头函数的this指向的测试如下:

posted @ 2022-07-31 11:28  JohnYang819  阅读(308)  评论(0编辑  收藏  举报