目錄
JSX是甚麼
JSX
是JavaScript的語法擴充
,長得頗像HTML,類HTML
其React
專案的切版時常見
,但因為是JS的語法擴充,所以可以在裡面使用JS功能
另外其優點是React DOM會在渲染前
將所有變數轉為字串
,以避免XSS
嵌入變數
function dateConvertor(date){
return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
}
function App(){
const frameWork = 'React';
const today = new Date();
const url = 'https://images.unsplash.com/photo-1532009871151-e1958667c80d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=200&q=80';
return (
<div className="container">
<h1>Hello {frameWork}</h1>;
<img src={url}/>
<p>{dateConvertor(today)}</p>
</div>
);
}
Vue對應寫法
<template>
<div class="container">
<h1>Hello {{frameWork}}</h1>
<img :src="url"/>
<p>today is {{dateConvertor(today)}}</p>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
name: 'App',
data() {
return {
frameWork:'React',
today:new Date(),
url:'https://images.unsplash.com/photo-1532009871151-e1958667c80d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=200&q=80',
};
},
methods:{
dateConvertor(date:Date):string{
return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
}
}
})
</script>
child & function component
在上個例子中可以發現撰寫JSX和Vue的template相當地相似
同樣地它也可以製作組件,並把它包到另一個組件裡
React的組件
有2種,分為function
component和class component
這個例子使用function component,組件的名稱開頭
一定要大寫
function HelloWorld(){
const element = (
<div>
<h1>Hello! Below are frameworks you can choose</h1>
<ul>
<li>Angular</li>
<li>React</li>
<li>Vue</li>
</ul>
</div>
);
return element;
}
export default HelloWorld;
import HelloWord from './HelloWord';
function APP(){
return (
<div>
<HelloWord></HelloWord>
</div>
);
}
Vue對應寫法
<template>
<div>
<HelloWorld></HelloWorld>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
name: 'App',
})
</script>
React.createElement() & element
(10/24更新)
React element
(或稱element)並不是實例,而是純JS物件
,因為是純物件所以不會指向螢幕上的任何東西
What’s important is that both child and parent elements are just descriptions and not the actual instances. They don’t refer to anything on the screen when you create them. You can create them and throw them away, and it won’t matter much.
它有type、props、key 3個欄位,其中只有key可以是null
且是immutable
的,一旦建立
,就不能改變
它的屬性。element就像是電影中的一個幀,代表特定時間點的UI。
props描述實例、DOM node該有的屬性
(ex: component type、children、className)
DOM element
DOM element並不是瀏覽器的DOM element,是指描述DOM node的React element
其type屬性是string,type會轉為tag name,props則會變成相應的屬性
例如JSX長這樣
function App(){
return (
<div className='container'>
<button className='bg-blue-600 text-white rounded'>
<span>BlueButton</span>
</button>
</div>
);
}
經由babel編譯後,變成呼叫React.createElement()的函式,這個函式會回傳React element
也就是說JSX只是createElement()的語法糖
const element = React.createElement(
'button',
{className: 'bg-blue-600 text-white rounded'},
<span>BlueButton</span>
)
{
type: 'button',
props: {
className: 'bg-blue-600 text-white rounded',
children: {
type: 'span',
props: {
children: 'BlueButton'
}
}
}
}
render()將其轉換成HTML
To render a React element, first pass the DOM element to ReactDOM.createRoot(), then pass the React element to root.render()
<button class='bg-blue-600 text-white rounded'>
<span>BlueButton</span>
</button>
component element
DOM element是指描述component的React element,其type屬性是function或class component
例如class component長這樣
class SimpleButton extends Component {
constructor(props) {
super(props);
this.state = { };
}
render() {
return (
<button className={`rounded p-2 ${this.props.className}`} onClick={this.props.click}>{this.props.children || 'save'}</button>
);
}
}
function App(){
return (
<div>
<SimpleButton className='bg-violet-400 hover:bg-violet-600 text-white'>VioletButton</SimpleButton>
</div>
);
}
babel編譯後得到的element
{
type: SimpleButton,
props: {
className:'bg-violet-400 hover:bg-violet-600 text-white',
children: 'VioletButton'
}
}
轉換成HTML
<button class="rounded p-2 bg-violet-400 hover:bg-violet-600 text-white">VioletButton</button>
render()
React
render()Root底下的方法,它接受ReactElement或JSXElementConstructor(回傳component或ReactElement的函式)作為參數
// JSX會被babel編譯成呼叫createElementK的函式,這個函式會回傳element
const element = <h1>Hello React</h1>;
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(element);
Vue
Vue的render function也差不多
render function,縮寫為h()
之所以是h是來自hyperscript()
<template>
<h1 class="container">
Hello React
</h1>
</template>
import { h } from 'vue'; // 這是render function
const vnode = h(
'h1', // type
{class: 'container'}, // props
'Hello React'
)
最後會得到一個VNode
參考資料
React - JSX
React - Rendering an Element into the DOM
React - React Components, Elements, and Instances
React - 不使用 JSX 開發 React