这篇文件是让我们了解React组件中父子组件是如何实现组件通信的。
请看下面这段代码:
import React,{Component} from "react";
import Header from './cnp/Header';
import Footer from './cnp/Footer'
import Main from "./cnp/Main";
import "./style.css"
export class App extends Component{
render(){
return (
<div className="app">
<Header></Header>
<Main></Main>
<Footer></Footer>
</div>
)
}
}
export default App;
这段代码是一个React组件,它包含了一个Header组件、一个Main组件和一个Footer组件。其中,Header和Footer组件是子组件,而Main组件是父组件。因为Main组件中又引入了两个组件并且向子组件传递了数据,所以这个组件就是父子组件。
Heaeder组件
代码如下所示:
import React,{Component} from "react";
export class Header extends Component{
render(){
return (
<div>Header</div>
)
}
}
export default Header
这段代码是Header组件的代码,它很简单,只是返回了一个包含文本“Header”的div元素。
Footer组件
代码如下所示:
import React,{Component} from "react";
export class Footer extends Component{
render(){
return (
<div>Footer</div>
)
}
}
export default Footer
这段代码是Footer组件的代码,返回了一个包含文本“Footer”的div元素。
Main组件
这里是我们的重点,代码如下所示:
import React,{Component} from "react";
import axios from "axios"
import MainBanner from "./MainBanner";
import MainProductList from "./MainProductList";
export class Main extends Component{
constructor(){
super()
this.state = {
banners:[],
productList:[]
}
}
componentDidMount(){
axios.get("http://123.207.32.32:8000/home/multidata").then(res=>{
const banners = res.data.data.banner.list;
const recommend = res.data.data.recommend.list;
this.setState({
banners,
productList:recommend
})
})
}
render(){
const { banners,productList } = this.state
return (
<div className="main">
<div>Main</div>
<MainBanner banners={banners} title="轮播图"></MainBanner>
<MainProductList productList={productList}></MainProductList>
</div>
)
}
}
export default Main
这段代码是Main组件的代码,它包含了一个MainBanner组件和一个MainProductList组件。在Main组件中,我们通过axios库向服务器发送了一个GET请求,获取了一些数据,并将这些数据存储在组件的state中。然后,我们将这些数据作为props传递给了MainBanner和MainProductList组件,以便它们可以在组件中使用这些数据。
这里我们要注意数据是如何从父组件传递向子组件的,可以看到我们的render
方法中,我们使用了this.state.banners
和this.state.productList
来获取父组件传递过来的数据(这里使用的是ES6的解构赋值语法,从this.state
中提取出banners
和productList
属性值),然后将其作为props传递给了子组件。传递方式和vue
中的props
传递方式有点类似<MainBanner banners={banners} title="轮播图"></MainBanner>
,只不过vue
中是使用v-bind
指令来传递的。
MainBanner组件
import React,{Component} from "react";
import PropTypes from "prop-types"
export class MainBanner extends Component{
// static defaultProps = {
// banners:[],
// title:"默认标题"
// }
constructor(props){
super(props)
this.state = {}
}
render(){
const { title,banners } = this.props
return (
<div>
<h2>封装一个轮播图:{title}</h2>
<ul>
{
banners.map(item => {
return <li key={item.acm} >{item.title}</li>
})
}
</ul>
</div>
)
}
}
// MainBanner传入的props类型进行验证
MainBanner.propTypes = {
banners:PropTypes.array,
title:PropTypes.string
}
// MainBanner传入的props的默认值
MainBanner.defaultProps = {
banners:[],
title:"默认标题"
}
export default MainBanner
这段代码是MainBanner组件的代码,它接收从父组件传递过来的banners
和title
两个props。然后使用这些数据渲染了一个轮播图。
在这里我们需要注意:这里的构造方法constructor
中,我们一定要使用super(props)
来调用父类的构造方法,这是因为在子类中,我们需要使用this.props
来访问父组件传递过来的props。假如如果没有调用super(props)
,那么this.props
将是一个undefined
,这样会导致子组件无法正确地访问到父组件传递过来的props。
然后在render
方法中,同样使用了this.props
来访问父组件传递过来的props,并使用这些数据渲染了一个产品列表。
这里我们一定要注意限制传入的数据类型,我们可以使用PropTypes
库来限制传入的数据类型。这里我们使用了PropTypes.array
和PropTypes.string
来限制传入的banners
和title
这两个props的数据类型。
这里我们注意单词拼写propTypes
和PropTypes
的区别,一定要注意哪里大写哪里小写!!!
那么我们如何来定义默认值呢?
我们可以使用defaultProps
来定义默认值,代码就和上面的一样,这里就不再赘述。接着我们来讲解MainProductList组件。
MainProductList组件
这个组件相对来说就比较简单了,代码如下所示:
import React,{Component} from "react";
export class MainProductList extends Component{
render(){
const { productList } = this.props
return (
<div>
<h2>商品列表</h2>
<ul>
{
productList.map(item=>{
return <li key={item.acm}>{item.title}</li>
})
}
</ul>
</div>
)
}
}
export default MainProductList
这段代码是MainProductList组件的代码,它接收从父组件传递过来的productList
props,并使用这些数据渲染了一个产品列表。
这里我们使用了this.props
来访问父组件传递过来的props,并使用这些数据渲染了一个产品列表。这里我们没有限定传入的数据类型,因为我们在父组件中已经限定了传入的数据类型。在这里我们注意如果想限定数据类型,一定要先引入prop-types
库,然后再使用PropTypes
来限定数据类型import PropTypes from "prop-types"
,还有我们上面讲的那个字母大小写的注意事项。
总结
以上就是React组件中父子组件的实现方法。在父组件中,我们可以通过props来向子组件传递数据。在子组件中,我们可以通过props来接收父组件传递过来的数据,并使用这些数据来渲染组件。
感谢大家观看,我们下次再见,最后附上我们最后生成的页面效果
of course like your web site but you need to test the spelling on quite a few of your posts. A number of them are rife with spelling problems and I in finding it very troublesome to inform the reality nevertheless I will surely come again again.
新年快乐!
十天看一部剧,还可以吧
@梦不见的梦 行,谢谢提醒,我优化一下
网站的速度有待提升,每次打开都要转半天还进不来呢
@React实战爱彼迎项目(二) - 程序员鸡皮 哪里有问题了,报错了吗?
@Teacher Du 那是怕你们毕不了业,我大学那会儿给小礼品
我们大学那会,献血还给学分~
@ab 我想去学网安,比如网警,但分也贼高😕
@夜 加油,你一样也可以成为程序员的,需要学习资料可以V我