將一個不可複用的元件改成清晰通用的可複用元件
class OneList extends React.Component {
constructor(props) {
super(props)
this.state = {
list: [],
}
}
componentDidMount() {
// 從api中載入一個訊息列表
fetch().then(list => {
this.setState({ list })
})
}
render() {
const { list = [] } = this.state;
return (
<ul>
{
list.map(item => (
<li key={item.id}>
<div>{item.userName}</div>
{item.choice && <div>{item.choice}</div>}
</li>
))
}
</ul>
)
}
}
複製程式碼
使用無狀態元件複寫一下這個列表
const TwoList = ({ list = [] }) => (
<ul>
{
list.map(item => (
<li key={item.id}>
<div>{item.userName}</div>
{item.choice && <div>{item.choice}</div>}
</li>
))
}
</ul>
)
複製程式碼
上面的元件是完全可以滿足正常工作需要的,但是遇到相同程式碼,再去複製程式碼往往不是最佳解決方案,但是可能會因為程式碼量少而不去對元件進行抽象和需要展示的資料進行解耦
編寫一個可複用的List元件
這裡的List元件不會包含狀態,所以可以將其改寫為無狀態的函式元件
const List = ({ list, userNameKey, choiceKey }) => (
// userName 用於指定需要顯示的屬性名,choice用於指定可選部分的屬性
<ul>
{
list.map(item => (
<Item
key={item.id}
userName={item[userNameKey]}
choice={item[choiceKey]}
/>
))
}
</ul>
)
const Item = ({ userName, choice }) => (
<li>
<div>{userName}</div>
{choice && <div>{choice}</div>}
</li>
)
複製程式碼
現在我們建立了兩個介面清晰的小型元件,優點:容易維護與測試,fix bug 更方便
使用元件
OneList
render() {
return (
<List
list={list}
userNameKey='userName'
choiceKey='choice'
/>
)
}
複製程式碼
TwoList
const TwoList = ({ list }) => (
<List
list={list}
userNameKey='userName'
choiceKey='choice'
/>
)
複製程式碼
現在已經完成了元件的建立,將一個單一需求的元件變得可複用,如果有新的需求,我們只需要改動一點程式碼就能完成所有地方的修改
相比冬天的磚,我還是喜歡秋天的磚,不那麼凍手···