[7天學會ReactJS] Day 6. 切分Component — Props

Andy Tsai
ReactMaker
Published in
8 min readSep 12, 2017

同學們好,今天要講解的是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>中使用到productcartaddToCart這三個元素,因此透過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中一樣,唯一的差別在於productcartaddToCart需要從props取得。

使用上為this.props.productthis.props.cartthis.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>中使用到cartdeleteCartItem這兩個元素,因此透過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中一樣,唯一的差別在於cartdeleteCartItem需要從props取得。

使用上為this.props.cartthis.props.deleteCartItem

這個章節講解了如何切分Component並透過props傳值到Component中使用。

實際開發時,可以先將程式碼寫到同一隻程式中,如同原本的Content.js一般,

當有其他頁面需要用到時,在切分成Component使用,切分方法如今天介紹的方法一樣,

可以看出來,只是將使用的變數或函式傳入Component並透過props使用,程式邏輯並無改變。

而我認為React要學得好,就在於Component如何設計到可以讓許多頁面共用。

--

--