React主打函數語言程式設計,配合上JSX語法,基本上可以把每個模組都封裝為單獨元件,用元件一時爽,一直用一直爽。
1.函式式元件
在React中最簡單的即是建立一個函式式,沒有生命週期的元件,這與 Vue 的單檔案 .vue 一個完整生命週期元件不同,舉個例子。
// 定義weblcome 元件
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
複製程式碼
這裡的props屬性物件是React中元件單向資料傳遞的唯一標示,在函式式元件中,我們可以通過 props.name 來獲取 其他元件傳遞的name 屬性,這點和Vue是沒有本質區別的。
// 子元件 獲取name屬性
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
// 父元件傳入name屬性
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
複製程式碼
2.class 元件
函式式元件由於沒有生命週期的定義,雖然簡潔,但是擴充方面較差,我們把上面的welcome,改寫為class元件
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
複製程式碼
welcome繼承自React.Component 組基類,在class元件中,作用域為當前元件,所以使用this物件來代替。
class元件有完整的生命週期,當元件插入到DOM中時,會依次呼叫生命週期函式。
render() 是class元件中必須實現的方法 當每次render 被觸發是都會檢查 this.props 和this.state 的變化、 同理適用於任何class 元件的檢查方式 所以在處理函式時,要考慮好應該在元件生命週期的那一步觸發,反之容易涼涼,或影響效能
3.順滑的元件抽取方式
每個class元件, 無論單獨呼叫,還是迴圈呼叫,都有自己的生命週期和單獨的state。
舉個實際場景。 比如:維護一個列表,列表中有, 全部,完成,失敗,進行中,等狀態type。 首先想到的是維護一個type 陣列,然後通過map 迴圈的方式來產生列表 好處是資料操作方便,缺點就是和其他 n個列表公用一個state ,沒有辦法將其中某個item的狀態區分開來
通過維護一個item元件,每個item都有自己的state,隨心所欲的操作
all in all 每個通過map 迴圈的item, 都可以根據業務考慮封裝為一個元件,因為你定義的時候就是一個變數, 不會像vue 通過v-for 指令渲染,後期抽離的成本不是很大。
Warning 如果shouldComponentUpdate 返回false 則不會render
當元件的props 或者state 變化時會觸發更新。 會依次執行下面的生命週期
- static getDerivedStateFromProps()
- shouldComponentUpdate() // 必要時來做效能優化,在第一期提過
- render() // 必須要用
- getSnapshotBeforeUpdate()
- componentDidUpdate() // 最常用的元件狀態更新判斷
最比較常用的除了 componentDidMount() 之外,還有 componentDidUpdate() 來判斷元件是否需要更新。
4.使用propTypes進行型別檢查 propsTypes 是React友好的型別檢查,通常和元件搭配使用。
使用方法非常簡單,上圖
二、 元件通訊方式 在單向通訊中,最常見的就是通過prop方式。
父 - 子
子元件定義好item引數 父元件按照propTyes進行傳參 子元件通過 this.props.item 取值
子 - 父
// 子元件
HomeItem.defaultProps = {
item: {},
// 定義回撥函式
fetchData: () => {},
};
HomeItem.propTypes = {
item: PropTypes.object,
fetchData: PropTypes.func,
};
複製程式碼
// 在子元件
handleSuccessDel = () => {
const successUrl = {
url: `/xq/statuses/destroy/${this.state.uid}.json`,
params: {},
};
const draftUrl = {
url: '/xq/statuses/draft/delete.json',
params: { id: this.props.item.textId },
};
const delUrl = this.props.item.typeName === '草稿' ? draftUrl : successUrl;
httpClient.post(delUrl.url, delUrl.params).then((res) => {
if (res.success) {
this.setState({
showModal: false,
});
Toast({ text: '刪除成功', type: 'success' });
// 通過引數執行父元件傳過來的callback 進而引起父元件狀態改變
this.props.fetchData();
}
}).catch((err) => {
console.error(err);
});
};
複製程式碼