父子组件的传值
在react中,父传子可以使用props的方法,子传父使用props的回调函数
父组件:
在父组件中定义state,将这个state对象传给子组件,所以可以直接在son组件上写{...this.state}
import React, { Component } from 'react'
import Son from './son'
export class Parent extends Component {
constructor() {
super()
this.state = {
name: '父组件',
msg: '这是父组件的信息'
}
}
render() {
return (
<div>
<h1>Parent Page</h1>
<h2>我是父组件的:{msg}--{name}</h2>
<Son {...this.state} parentChange={this.parentChange.bind(this)}/>
</div>
)
}
}
export default Parent
子组件:
在state中写入parentMsg: props.msg,这样在页面中可以直接展示parentMsg,也就是父组件传过来的值
import React, { Component } from 'react'
export class Son extends Component {
constructor(props) {
super()
this.state = {
name: '子组件',
msg: '这是子组件的内容',
parentMsg: props.msg
}
}
render() {
// 在这种父子组件中需要用到同样的属性名的时候,我们会选择定义别名进行区分
let { name, msg, parentMsg } = this.state
return (
<div>
<h1>Son Page</h1>
<p>{name}-{msg}</p>
<p>父组件传过来的值{parentMsg}</p>
</div>
)
}
}
export default Son
父子组件重名问题解决
父组件中有name,msg,子组件也有该变量的名字,如果想要一起使用该如何操作呢?
在子组件中,state中的是自己的,props中的是从外面传进来的,所以我们可以给props中的变量起一个别名:
如果不想用别名的话,我们也可以直接用this.state.name,this.props.name
import React, { Component } from 'react'
export class Son extends Component {
constructor(props) {
super()
this.state = {
name: '子组件',
msg: '这是子组件的内容',
parentMsg: props.msg
}
}
render() {
// 在这种父子组件中需要用到同样的属性名的时候,我们会选择定义别名进行区分
let { name: pName, msg: pMsg } = this.props
let { name, msg, parentMsg } = this.state
return (
<div>
<h1>Son Page</h1>
<p>{name}-{msg}</p>
<p>父组件传过来的值{parentMsg}-{pName}-{pMsg}</p>
</div>
)
}
}
export default Son
子组件改变父组件的值
我们在子组件中定义一个输入框,希望通过这个输入框改变父组件展示的值:
思路:父组件中写方法,子组件中进行调用
父组件:
1.定义函数parentChange,将里面的data作为参数传进来
2.将该方法传给子组件
import React, { Component } from 'react'
import Son from './son'
export class Parent extends Component {
constructor() {
super()
this.state = {
name: '父组件',
msg: '这是父组件的信息'
}
}
// 如果要让子组件改父组件的值的话就需要定义这个函数
parentChange(data) {
console.log(data)
this.setState({msg: data})
}
render() {
let { name, msg } = this.state
return (
<div>
<h1>Parent Page</h1>
<h2>我是父组件的:{msg}--{name}</h2>
{/* 子组件改父组件的值,就把父组件的改值事件传给子组件进行一个回调 */}
<Son {...this.state} parentChange={this.parentChange.bind(this)}/>
</div>
)
}
}
export default Parent
子组件:
1.给输入框绑定onChange函数
2.在handleChange函数中调用父组件传进来的方法this.props.parentChange(e.target.value),传进去的值就是input输入的值
import React, { Component } from 'react'
export class Son extends Component {
constructor(props) {
super()
this.state = {
name: '子组件',
msg: '这是子组件的内容',
parentMsg: props.msg
}
}
handleChange = (e) => {
this.setState({parentMsg: e.target.value})
// 这里对父组件传过来的方法进行调用
this.props.parentChange(e.target.value)
}
render() {
// 在这种父子组件中需要用到同样的属性名的时候,我们会选择定义别名进行区分
let { name, msg, parentMsg } = this.state
return (
<div>
<h1>Son Page</h1>
<p>{name}-{msg}</p>
<p>父组件传过来的值{parentMsg}</p>
<input type="text" value={parentMsg} onChange={this.handleChange} />
</div>
)
}
}
export default Son
传值校验
如果我们要对传值的类型进行校验应该怎么做呢?
这里进行验证主要是为了提高我们代码的可读性,便于协同开发,提高效率。
进行传值校验,我们需要用到prop-types,在react15版本以后,prop-types是另外的一个包,需要手动下载。
下载完成之后,直接在子组件页面顶部进行引入:
import PropTypes from 'prop-types'
在子组件里面进行传值类型校验:
使用语法:组件名.propTypes添加一个属性,属性值为对象
Son.propTypes = {
name: PropTypes.string.isRequired, // 给isRequired属性代表必传项,不传就会报错
msg: PropTypes.string
}
// 如果需要制定默认值则像下面这样使用
Son.defaultProps = {
name: 'beiyu',
msg: '学习react'
}