[7天學會ReactJS] Day 6. 切分Component — Props
同學們好,今天要講解的是React另一個很重要的props
,使用到props
的時機點是要將值傳給其他Component時,因此今天也會講解如何切分Component。
切分Component
實行專案時不可能將所有程式碼都放在同一隻JS檔案中,會相當難維護。
切分Component除了讓程式碼提升維護性外,也可以運到在React的特點:Reuse
,
當一個元件會讓許多頁面使用時,就必須將它做成Component供各頁面使用。
例如,有個使用者資訊許多頁面都會用到,我們就可以將它切出來作為Component。
需要用到的頁面,就可以自行載入使用,如下所示:
import User from '../User';<User name="ReactMaker" desc="用愛心來做事,用感恩的心做人" src="profile.png" />
Props
Props使用時機通常是父元件傳值到子元件的情況下。
Props是單向的,也就是只能由父元件傳到子元件,子元件無法傳到父元件。
當子元件需要傳值到父元件時,可以透過父元件傳函式至子元件,子元件執行函式並將值帶入,
子元件用this.props
來存取props
。
// parent<User name="ReactMaker" desc="用愛心來做事,用感恩的心做人" src="profile.png" />// Userthis.props.name; // "ReactMaker"
this.props.desc; // "用愛心來做事,用感恩的心做人"
this.props.src; // "profile.png"
本日目標
將商品資訊及購買物品切分Component。
[最終成果]
1. 商品資訊Component
[程式碼]
// Content.jsimport Product from './Product';...<Product
product={product}
cart={cart}
addToCart={this.addToCart}
/>
我們將原本放在Content.js
中商品資訊的<Card>
切分成<Product>
Component使用,並透過import Product from './Product
載入。
由於原本<Card>
中使用到product
、cart
、addToCart
這三個元素,因此透過props
傳入<Product>
中使用。
// Product.jsimport React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Button, Card, CardImg, CardBlock, CardTitle, CardSubtitle, CardText, Badge } from 'reactstrap';export default class Product extends Component {
static propTypes = {
product: PropTypes.object,
cart: PropTypes.array,
addToCart: PropTypes.func,
}
render() {
return (
<Card>
<CardImg width="100%" src={this.props.product.img} alt="Card image cap" />
<CardBlock>
<CardTitle>{this.props.product.title}</CardTitle>
<CardSubtitle>
<h4>
{
this.props.product.discount
? <Badge color="danger">特價:{this.props.product.price}</Badge>
: <Badge color="success">售價:{this.props.product.price}</Badge>
}
</h4>
</CardSubtitle>
<CardText>{this.props.product.desc}</CardText>
<Button
disabled={this.props.cart.find(item => item.id === this.props.product.id)}
color="secondary"
onClick={() => this.props.addToCart(this.props.product)}
>
購買
</Button>
</CardBlock>
</Card>
);
}
}
此處的程式基本上和原本放在Content.js
中一樣,唯一的差別在於product
、cart
、addToCart
需要從props
取得。
使用上為this.props.product
、this.props.cart
、this.props.addToCart
。
2. 購買物品Component
[程式碼]
// Content.jsimport Cart from './Cart';...<Cart
cart={cart}
deleteCartItem={this.deleteCartItem}
/>
我們將原本放在Content.js
中購買物品的<Table>
切分成<Cart>
Component使用,並透過import Cart from './Cart
載入。
由於原本<Table>
中使用到cart
、deleteCartItem
這兩個元素,因此透過props
傳入<Cart>
中使用。
// Cart.jsimport React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Table, Alert, Button } from 'reactstrap';export default class Cart extends Component {
static propTypes = {
cart: PropTypes.array,
deleteCartItem: PropTypes.func,
} render() {
const totalPrice = this.props.cart.reduce((acc, item) => (acc += item.price), 0); return (
<div>
<Table>
<thead>
<tr>
<th>#</th>
<th>品項</th>
<th>價格</th>
<th />
</tr>
</thead>
<tbody>
{
this.props.cart.map((item, index) => (
<tr>
<th scope="row">{index + 1}</th>
<td>{item.title}</td>
<td>{item.price}</td>
<td><Button color="danger" onClick={() => this.props.deleteCartItem(index)}>X</Button>{' '}</td>
</tr>
))
}
</tbody>
</Table>
<Alert color="success" className="text-right">
總價:
{totalPrice}
元
</Alert>
</div>
);
}
}
此處的程式基本上和原本放在Content.js
中一樣,唯一的差別在於cart
、deleteCartItem
需要從props
取得。
使用上為this.props.cart
、this.props.deleteCartItem
。
這個章節講解了如何切分Component並透過props
傳值到Component中使用。
實際開發時,可以先將程式碼寫到同一隻程式中,如同原本的Content.js
一般,
當有其他頁面需要用到時,在切分成Component使用,切分方法如今天介紹的方法一樣,
可以看出來,只是將使用的變數或函式傳入Component並透過props
使用,程式邏輯並無改變。
而我認為React要學得好,就在於Component如何設計到可以讓許多頁面共用。