P14:React进阶-父子组件的传值
通过上篇文章的学习,已经把”美女”组件做了一个基本的拆分,但是还不能实现随着输入,显示出输入的内容。这里涉及的是父组件向子组件传值。然后点击删除,就相当于子组件向父组件传值。本文就主要学习一下父子组件传值的一些技巧。
父组件向子组件传值
这里只介绍最实用的,最快速的上手方法。就是使用组件属性的形式父组件给子组件传值。比如:我们在<MeinvItem>
组件中加入content
属性,然后给属性传递{item}
,这样就完成了父组件向子组件传值。
<MeinvItem content={item} />
现在值已经顺利的传递了过去,这时候可以通过this.props.xxx
的形式进行接受,比如传递过来的值,可以用如下代码进行接收。
import React, { Component } from 'react'; //imrc class MeinvItem extends Component { //cc render() { return ( <div>{this.props.content}</div> ); } } export default MeinvItem;
修改完美女子项的组件后,可以打开浏览器进行预览了。
试着添加几个新的选项试一下,比如美女踩背。
玩笑归玩笑,学到这里你要记住一点:父组件向子组件传递内容,靠属性的形式传递。
子组件向父组件传递数据
现在要作这样一个功能:点击组件中的菜单项后,删除改菜单项。在前边的教程中已经学习了这个知识,只是现在组件拆分了,就涉及了一个子组件向父组件传递数据的知识需要掌握。
先来绑定点击事件,这时候当然是要在MeinvItem
组件中绑定了,代码如下:
import React, { Component } from 'react'; //imrc class MeinvItem extends Component { //cc render() { return ( <div onClick={this.handleClick}>{this.props.content}</div> ); } handleClick(){ console.log('撩拨了小姐姐') } } export default MeinvItem;
这时候进行预览,打开 F12,再点击服务菜单项,就会再console
里显示出”撩拨了小姐姐”的字样。但是console
里还有一个warning
警告,这个警告我们见过,就是要求循环时必须设置 key 值。
修改Meinv
组件的render
代码如下:
<ul> { this.state.list.map((item,index)=>{ return ( <MeinvItem key={index+item} content={item} /> ) }) } </ul>
绑定成功后,现在就要通过操作子组件删除父组件里的数据了。但是 React 有明确规定,子组件时不能操作父组件里的数据的,所以需要借助一个父组件的方法,来修改父组件的内容。其实在以前已经写了一个删除方法deleteItem
,现在要作的就是子组件调用这个方法。
//删除单项服务 deleteItem(index){ let list = this.state.list list.splice(index,1) this.setState({ list:list }) }
获取数组索引下标
那现在问题来了,要删除就要知道索引值,还是需要通过父组件传递给子组件。这里还是通过props
属性的形式进行传递。
<ul> { this.state.list.map((item,index)=>{ return ( <MeinvItem key={index+item} content={item} index={index} /> ) }) } </ul>
然后修改MeinvItem
组件,在handleClick
方法里,写入下面代码:
handleClick(){ console.log(this.props.index) }
这时候预览一下,你会发现点击后报错,错误还是我们的老朋友没有bind(this)
。
那可以用以前的老方法绑定 this.
return ( <div onClick={this.handleClick.bind(this)}> {this.props.content} </div> );
这样是可以解决的,但是肯定会有小伙伴说,我看别人不是这样写的,而是在构造函数里绑定的。(有言曰:构造函数中绑定性能会高一些,特别是在高级组件开发中,会有很大的作用)
constructor
绑定 this 方法。
import React, { Component } from 'react'; //imrc class MeinvItem extends Component { //cc //--------------主要代码--------start constructor(props){ super(props) this.handleClick=this.handleClick.bind(this) } //--------------主要代码--------end render() { return ( <div onClick={this.handleClick}> {this.props.content} </div> ); } handleClick(){ console.log(this.props.index) } } export default MeinvItem;
子组件调用父组件方法
如果子组件要调用父组件方法,其实和传递数据差不多,只要在组件调用时,把方法传递给子组件就可以了,记得这里也要进行this
的绑定,如果不绑定子组件是没办法找到这个父组件的方法的。
<ul> { this.state.list.map((item,index)=>{ return ( <MeinvItem key={index+item} content={item} index={index} //关键代码-------------------start deleteItem={this.deleteItem.bind(this)} //关键代码-------------------end /> ) }) } </ul>
传递后,在MeinvItem
组件里直接用就可以了,代码如下:
handleClick(){ this.props.deleteItem(this.props.index) }
到此为止,就算是实现了子组件向父组件传值。
特别提醒:本文内容是 React 体系中非常重要的一节,小伙伴们可以多看几遍,并进行练习。因为真正的 React 开发工作,每天写的就是各种组件,传值是组件之间产生联系的必要一环,无法跳跃。所以一定要学好。
码云笔记 » P14:React进阶-父子组件的传值