1-6、React组件中传值、添加事件和this丢失问题

文章系列(React框架基础)

1-1、React环境搭建,以及初识jsx语法。
1-2、React熟悉,jsx语法以及变量绑定和三种渲染语句
1-3、React绑定属性和事件,以及事件的响应。
1-4、React中form表单下的input框初使用以及列表渲染
1-5、React初探组件化开发,高内聚低耦合
1-6、React组件中传值、添加事件和this丢失问题(本文)

大家好,我是Counterrr
不忘初心,砥砺前行

本文目录

一、组件中传值;
二、添加事件和this丢失问题;

(tips:本文为我们React框架基础系列最后一篇,下个系列将开启React组件化开发和项目实战)

1、组件中传值:

好的在上节5、React初探组件化开发,高内聚低耦合中我们用react组件化开发的思想将之前的小项目重构了,最后的效果如下:
在这里插入图片描述
我们知道组件化开发最大的好处就是组件的复用,但是在我们这个小项目中Option组件即如下图:在这里插入图片描述
当我们去复用的话还是react,写死的状态,将Options组件写成如下代码:

class Options extends React.Component {
    render () {
        return (<ul>
                <Option/>
                <Option/>
                <Option/>
            </ul>)
    }
}

在这里插入图片描述
我们看到这显然不是我们想要的结果,我们要的复用是,可以去暴露接口让我们去定制想要的内容。那么在没有组件化重构之前我们是怎么去做这件事情的,我们是将对象定义在全局上,对象上有数组,去渲染这个数组,那么在我们组件化开发中直接在类render( )方法上去定义我们的数组,从而传值给我们的子组件,代码如下:

class MySelectLanApp extends React.Component {
    render () {
        let obj = {
            "title": "今天学习什么语言?",
            "des": "大家好,我是Counterrr",
            "tips": "不忘初心,砥砺前行",
            "languages": ['React', 'Vue', 'php']
        }
        return (<div>
            <Header obj={obj}></Header>
            <main>
                <ButtonActive languages={obj.languages}></ButtonActive>
                <AddLang languages={obj.languages}></AddLang>
                <Options languages={obj.languages}></Options>
            </main>
        </div>)
    }
}

可以看到我们直接在每个组件上直接写上属性,然后将值传入。接着我们在Options组件上这样去渲染:

class Options extends React.Component {
    render () {
        return (<ul>
                <Option languages={this.props.languages}/>
            </ul>)
    }
}

我们可以看到这边采用this.props.languages去获取这个数组。render函数定义在类的原型上我们去调用render里的this可以打印出组件实例对象,从而去获取绑定在实例对象上的props字段下的languages数组,紧接着我们又将这个数组以languages属性传递给了Option组件,Option组件写成如下:

class Option extends React.Component {
    render () {
        return (
            this.props.languages.map((item, index) => {
            return <li key={`option${index}`}>{item}</li>
            })
        )
    }
}

我们在Option组件里再用我们map方法去真实的渲染,页面如下:
在这里插入图片描述
Header组件代码如下:

class Header extends React.Component {
	render () {
        console.log(this)
		return (<header>
                <div>{this.props.obj.title}</div>
                <div>{this.props.obj.des}</div>
                <div>{this.props.obj.tips}</div>
            </header>)
	}
}

组件之间传值还是比较简单的,我们在组件标签上去绑定属性,然后在组件render方法上去使用this.props去获取我们自定义的属性。

2、添加事件和this丢失问题:

添加事件,在没有重构之前,我们也是将事件函数定义在全局上,通过onClick去绑定这个事件函数,那我们重构后,也是将事件函数定义这个组件的类里,我们拿AddLang这个组件来写一下,这个组件也是传入languages属性并且将对象上的languages数组传入,AddLang组件代码如下:

class AddLang extends React.Component {
    submitFunc (e) {
        e.preventDefault();
        if (e.target.elements.languages.value == '') {
            alert('请输入!');
        }
        else {
            console.log(this.props.languages)
        }
    }
    render () {
        return  (<form onSubmit={this.submitFunc}>
                    <div>
                        <input type="text" name="languages"></input>
                        <button>添加语言</button>
                    </div>
                </form>)
    }
}

我们可以看到我们还是在form上去监听原生的submit事件,并且这个函数写在了AddLang这个类里,那就相当于在创建这个对象实例的时候,submitFunc绑定在了这个原型上,那么在这个函数执行的时候this就指向这个类的实例对象。我们来点击下添加语言这个按钮看看,效果如下:
在这里插入图片描述
没问题,显示让我们输入,那我们就输入再试试:
在这里插入图片描述
我们发现报错了,Cannot read property 'props' of undefined这段代码我们熟悉的不能再属性,那这个是什么意思呢,读取不到undefined上的props属性,那为什么会这样呢,这个this不是指向这个AddLang创建出来的实例对象吗,并且在组件传值那已经把languages给传入,那这个就是this丢失的问题了,当我们点击这个按钮,说明这个函数自执行而不是给到我们对象去调用,那么这个this指向非严格模式下就指向window,严格模式下就指向undefined,那这边走的是严格模式,那这个this就是undefined
那我们怎么去解决这个问题呢?我们可以这样写:

class AddLang extends React.Component {
    constructor(props) {
        super(props)
        this.submitFunc = this.submitFunc.bind(this)
    }
    submitFunc (e) {
        e.preventDefault();
        if (e.target.elements.languages.value == '') {
            alert('请输入!');
        }
        else {
            console.log(this.props.languages)
        }
    }
    render () {
        return  (<form onSubmit={this.submitFunc}>
                    <div>
                        <input type="text" name="languages"></input>
                        <button>添加语言</button>
                    </div>
                </form>)
    }
}

我们用到这个类里constructor构造函数,在这个类实例化的时候就是去执行这段代码,我们将submitFunc函数的指向用bind函数给改变了,对于bind这块可以查看浅谈JavaScript的函数的call( ) apply( ) bind( )我的这篇博客。这样的话我们输入再去点击:
在这里插入图片描述
就会把this.props.languages给打印出来。

发布了31 篇原创文章 · 获赞 27 · 访问量 7955

猜你喜欢

转载自blog.csdn.net/weixin_44103733/article/details/105751221
今日推荐