JSX 若要根據 State 做不同的顯示,當然可以將 JavaScript 直接寫在 JSX 內,但比較好的方式是抽成 Method 或 Function,如此可避免 JSX 內 HTML 與 JavaScript 混在一起的 Spaghetti Code。
Version
macOS Mojave 10.14.6
WebStorm 2019.2.3
Node 12.11.0
Yarn 1.19.0
create-react-app 3.1.2
React 16.10.1
Class Component
import React, { Component } from 'react';
export default class extends Component {
state = {
isOn: true,
};
toggleState = () => {
this.setState(prevState => ({ isOn: !prevState.isOn }));
};
showTitle = () => this.state.isOn ? '+' : '-';
render() {
return (
<div>
<button onClick={ this.toggleState }>Toggle</button>
<div>{ this.showTitle() }</div>
</div>
);
}
}
第 4 行
state = {
isOn: true,
};
定義 isOn
state,其初始值為 true
,將來會 toggle 此值。
第 8 行
toggleState = () => {
this.setState(prevState => ({ isOn: !prevState.isOn }));
};
使用 setState()
更改 state,其中 prevState
argument 回傳回前一次的 state,藉由 !prevState.isOn
可 toggle state。
14 行
render() {
return (
<div>
<button onClick={ this.toggleState }>Toggle</button>
<div>{ this.showTitle() }</div>
</div>
);
}
render()
負責 return JSX,其中 <div>
會根據 isOn
state 有不同的結果,當然可以直接寫在 JSX 內,但這樣 JavaScript 邏輯與 JSX 混雜不易閱讀,比較好的方式是抽成 showTitle()
method。
12 行
showTitle = () => this.state.isOn ? '+' : '-';
根據 isOn
state 結果顯示 +
或 -
。
Function Component
import React, { useState } from 'react';
export default () => {
let [isOn, setIsOn] = useState(true);
let toggleState = () => setIsOn(prevState => !prevState);
let showTitle = () => isOn ? '+' : '-';
return (
<div>
<button onClick={ toggleState }>Toggle</button>
<div>{ showTitle() }</div>
</div>
);
};
第 4 行
let [isOn, setIsOn] = useState(true);
使用 useState()
建立 isOn
state 與 setIsOn()
setter,並直接傳入初始值 true
。
第 6 行
let toggleState = () => setIsOn(prevState => !prevState);
定義 toggleState()
,使用 setIsOn()
setter 設定 isOn
state,直接使用 !
對 prevState
argument 做 toggle。
10 行
return (
<div>
<button onClick={ toggleState }>Toggle</button>
<div>{ showTitle() }</div>
</div>
);
直接 return JSX,其中 <div>
會根據 isOn
state 有不同的結果,當然可以直接寫在 JSX 內,但這樣 JavaScript 邏輯與 JSX 混雜不易閱讀,比較好的方式是抽成 showTitle()
。
第 8 行
let showTitle = () => isOn ? '+' : '-';
定義 showTitile()
,根據 isOn
state 顯示 +
或 -
。
Conclusion
- 與 counter 不同的是本範例在 JSX 會根據
isOn
state 結果做不同顯示,傳統對 JSX 的批評大都是 JavaScript 與 HTML 混在一起,造成所謂 spaghetti code,但事實上無論 class component 或 function component,顯示邏輯都可抽成 method 或 function,因此 JSX 只要 coding style 好,就不會有維護問題