【React】如何利用props实现react组件复用

201 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

本文主要内容:通过编写一个网页来初步掌握react中props的用法,体会组件复用的奥妙

今天跟着写了一个仿照airbnb的页面,初步体会了react中组件复用的方法,也就是类似函数传参,通过同一个组件转入数据,进而展示多个结构相同内容不同的组件,非常的酷。接下来就通过记录一下自己写类似的一个旅行日记的网页的过程,来总结一下组件复用与props使用的一些相关知识点。

项目预览与分析

是figma上的一个旅行日记的网页,如下面的截图所示

image.png

我们要做的事就是将中间那张卡片复现出来

F$TJL953T~J}E2QC8PL5}`I.png

而最关键的就是将棕色框的组件编写出来后复用,所以接下来我们将主要着眼于这一块的编写

一笔带过其他部分

我会在文章结尾处放上我写的整个项目的github链接,里面包括我找的关于这个项目的所有资源以及自己写的一些源码,放在这里太占篇幅,所以这里仅仅阐述一下必要的部分

首先是HTML文件,基础的定义已经写了很多遍了,这里放一下,head里的前三行link是引入了google的Inter字体

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Alegreya&family=Inter:wght@500&display=swap" rel="stylesheet">
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <link rel="stylesheet" href="./index.css">
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Travel Journal</title>
  </head>
  <body>
    <script type="text/babel" href="../src/index.js"></script>
    <div id="root"></div>
  </body>
</html>

然后是js文件,中间是App.js定义的主要页面,顶部橙红色是Header.js定义的组件,下面三个是Card.js定义的组件进行三次复用得到的,至于复用的data.js文件也已经上传到了github(因为没去过什么地方,确实写不了自己的,就直接用了他的)。

Card.js接下来会详细讲,Header.js主要的就是一个CSS布局值得再记忆一下,在.header中输入下面三行实现竖直和水平的双居中。

    display: flex;
    justify-content: center;
    align-items: center;

至于最后的CSS文件,值得单独一提的已经写在上面了,其他的在文件中再看即可。

编写单个不复用的组件

首先我们以富士山为例,不考虑接下来的复用,将数据直接填入其中渲染

import React from "react";

export default function Card(){
    return (
        <div>
            <div className="card">
                <img className="card--image" src="./image/Japan.jpg" alt="pic"/>
                <div className="card--info">
                    <div className="card--line1">
                        <img src="./image/location.png" alt="loc"/>
                        <div className="location">JAPAN</div>
                        <a href="https://goo.gl/maps/1DGM5WrWnATgkSNB8">View on Google Maps</a>
                    </div>
                    <h1 className="title">Mount Fuji</h1>
                    <div className="date">12 Jan, 2021 - 24 Jan, 2021</div>
                    <div className="decription">Mount Fuji is the tallest mountain in Japan, standing at 3,776 meters (12,380 feet). Mount Fuji is the single most popular tourist site in Japan, for both Japanese and foreign tourists.</div>
                </div>
            </div>
            <hr className="line"/>
        </div>
    )
}

可以得到如上代码,这时如果我们想要编写下一个悉尼歌剧院的组件,可能需要复制一遍,然后逐一修改里面的内容,比如把title改为Sydney Opera House。这个事不符合计算机人优雅的特点,于是我们就有了组件复用的好办法。

利用props获取数据

要向组件中填入数据,当然需要获取数据,这就用到了一个相当重要的东西props,即接收的参数

回到调用Card组件的父组件App组件处,通过map方法获取传入的一系列参数

map()是js的一个方法,可以理解为接收一个数组,然后通过设定的方法函数,转换成一个新的数组返回

所以这里我们可以写如下代码,来返回数组元素为三个div的数组,其中每一个div可以视作一个对象

import data from "./data";
const cards = data.map(item =>{
  return (
    <Card 
      key={item.id}
      {...item}
      />
  )
})

这里是我选择使用的办法,当然还有逐一传送data和利用item直接传送两种办法,不再赘述。

所以在下面使用<Card />组件的时候,直接以定义好的{cards}数组替换即可

使用获取到的数据

import React from "react";

export default function Card(props){
    return (
        <div>
            <div className="card">
                <img className="card--image" src={`./image/${props.imageUrl}`} alt="pic"/>
                <div className="card--info">
                    <div className="card--line1">
                        <img src="./image/location.png" alt="loc"/>
                        <div className="location">{props.location}</div>
                        <a href={props.googleMapsUrl}>View on Google Maps</a>
                    </div>
                    <h1 className="title">{props.title}</h1>
                    <div className="date">{props.startDate} - {props.endDate}</div>
                    <div className="decription">{props.description}</div>
                </div>
            </div>
            <hr className="line"/>
        </div>
    )
}

最重要的一点当然是在Card后的括号里选择接收数据,这里使用形参props,当然也可以使用其他的

然后再用访问对象的方式分别将需要的数据填入,这里需要注意一下的是图像文件的src的填写方法

最后,我们就完成了这一个小小组件的三次复用,成功构建了下面的成果页面

image.png

详细props和mapping教学链接:scrimba.com/playlist/pq…

figma设计链接:www.figma.com/file/QG4cOE…

我的github链接:github.com/newfish-cmy…