30天的旅程已經快接近尾聲,接下來我分享我遇到前端工作上的一些經驗。
這是由我們團隊的D君最近在首頁上做的優化,IntersectionObserver更方便做滾動時版位的延遲載入;不支援IE,沒關係就直接放棄IE;因為實在太好用,其實有polyfill可用在IE上。
let observer = new IntersectionObserver(
slotsEle => {
if (slotsEle[0].intersectionRatio <= 0) return
if (!showSlots[slotsEle[0].target.id]) {
this.callAjaxData(slotsObj[0].value, slotsEle[0].target.id, observer)
observer.unobserve(slotsEle[0].target)
}
},{
rootMargin: '200px 0px 200px 0px'
}
)
observer.observe(document.querySelector(`#${slotsObj[0].id}`))
簡短如上,就可以完成延遲call ajax呼叫版位資料。
父層這樣寫:
this.state = {
tabs: [
{
title: "表1",
data: [],
link: "/xxx"
},
{
title: "表2",
data: [],
link: "/yyy"
}
]
}
<SwitchTabContent
tabs={tabs}
activeIndex={currentTabIndex}
>
{
<EReportList />
}
</SwitchTabContent>
SwitchTabContent.jsx這樣寫:
const {
children
} = props
return children ? React.Children.map(children, (child, index) => {
if (data) {
return React.cloneElement(child, {
data: data,
key: "child_" + index,
conditions: conditions,
activeIndex
});
} else {
return child;
}
}) : false;
做出來如下圖:
就是因為這個switchTab用到不只是這兩個地方,所以會想把它做成React.Children來使用。
這張圖應該還沒忘記,中間的middleware我們使用redux-saga
BasketAction
export const getBasketItems = props => {
return {
type: ENUM_BASKET_ACTION['GET_BASKET_ITEMS'],
...props
}
}
BasketSaga
function* watchGetBasketItems() {
yield takeEvery(ENUM_BASKET_ACTION['GET_BASKET_ITEMS'], asyncGetBasketItems)
}
function* asyncGetBasketItems({ cartCollection, currentChannel, currentID }) {
try {
const { response, error } = yield call(requestAjax, {
url: '/api/GetBasketItems',
data: {
id: currentID
}
})
if (response) {
let basketItems = response.data
yield put({
type: ENUM_BASKET_ACTION['UPDATE_BASKETS_ITEMS'],
basketItems
})
} else {
handleAjaxError(error)
}
} catch (error) {
console.log(error)
}
}
BasketReducer
const BasketReducer = (state = {}, action) => {
switch (action.type) {
case ENUM_BASKET_ACTION['UPDATE_BASKETS_ITEMS']:
let { basketItems } = action
return {
...state,
cartCollection: {
...state.cartCollection,
[action.currentID]: {
...basketItems
}
}
}
}
}
How to use it in Container:
export const BasketContainerConnect = connect(
state => ({ ...state.basketState }),
dispatch => ({
getBasketItems: props => dispatch(getBasketItems(props))
})
)(BasketContainer)
基本上就是按照redux的設計理念來做。
麻煩的其實是處裡從後端api拿到的資料結構,原則就是盡量保持原始資料的結構。