# 1222 React
## 範例01
```
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
<!-- 以下載入react 17.0.1-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.development.min.js"></script>
<!-- 以上載入react -->
<!-- 以下載入babel.js JSX即時轉譯器 效能不好-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.js"></script>
<!-- 以上載入babel.js-->
</head>
<body>
<div id="app"></div>
<script type="text/babel" src="app.js"></script>
<!-- type="text/babel" 會將app.js用babel做編譯-->
</body>
</html>
```
要使用React要在html引入
```
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.development.min.js"></script>
```
以及轉譯器
`<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.js"></script>`
會轉譯React中的JSX語法
`<script type="text/babel" src="app.js"></script>`
加上babel標籤會將src="app.js"以babel做編譯
---
```
ReactDOM.render(
<div>
<h1>Hello, world!!</h1>
<h2>Hello, react!!</h2>
</div>,
document.getElementById('app')
)
```
### JSX語法 不是原生JS
ReactDOM.render(JSX元素,html動元素)
JSX元素只能有一個元素,所以要放多個元素要用div包成一個元素
---
## 範例02:Component
```
function FunctionalComponent(){
return(
<div className="functional-component">
這是functionalComponent組件
<br/>
今天日期:
{
new Date().toDateString()
}
</div>
)
}
ReactDOM.render(
<div>
<div/> //在JSX中可以自己結束自己
<FunctionalComponent/>
<FunctionalComponent/>
<FunctionalComponent/>
<FunctionalComponent/>
</div>
,
document.getElementById('app')
)
```
* `React.Component`已經是舊寫法少用,新專案不用
* 只要是React的Component的function名稱嚴格規定要用大寫開頭"F"unctionalComponent,用小寫會出錯會被判斷為html標籤
* JSX元素支援JavaScript寫法,所以元素中出現`Date().toDateString()`有括弧的寫法,都會進行JS運算
* `<div className="functional-component">`要用classNameb如果用class雖然會動但在開發者工具會報錯
---
## 範例03:props
```
function FunctionalCard(props){
return (
<div className="card">
<img className="img" src={props.img} />
<div className="name">{props.name}</div>
<div className="quote">{props.children}</div>
</div>
);
}
```
* props是function的參數,只會有一個,雖然不是專有名詞但是統一用props
* children是特殊內建專用字不可亂改,會將FunctionalCard其他未指定名稱的參數放入
---
```
ReactDOM.render(
<div>
<FunctionalCard
img="http://fakeimg.pl/200x80/?text=milkmidi"
name="Component" />
<FunctionalCard
img="http://fakeimg.pl/200x80/ff0000/?text=pipi"
name="Component">
<h1>這裡可以放 children </h1>
</FunctionalCard>
</div>
);
```
```
<FunctionalCard
img="http://fakeimg.pl/200x80/?text=milkmidi"
name="Component" />
```
* 寫法像html的屬性,這裡的img,name都是自定義的名稱,會代入到FunctionalCard的props
*
---
## 範例4:State
```
function Counter() {
var [count, setCount] = React.useState(0);
return (
<div className="counter">
<h1>Counter</h1>
<div className="count">{count}</div>
</div>
);
}
ReactDOM.render(
<div>
<Counter/>
</div>
,
document.getElementById('app')
);
```
* State是Component自身的變數,可以有多個State
* `var [count, setCount]`一般寫法[name,setName]要寫成一組(不成文規定),setCount是修改數值用,不能直接改count
* `function Counter(props) {
var [count, setCount] = React.useState(0);
......`
意思為Counter這個function有一個變數count其初始值為0
如果要render多個Counter並帶不同初始值可以改寫成
```
function Counter(props) {
var [count, setCount] = React.useState(props.count);
return (
<div className="counter">
<h1>Counter</h1>
<div className="count">{count}</div>
</div>
);
}
ReactDOM.render(
<div>
<Counter count={0} />
<Counter count={1} />
</div>
,
document.getElementById('app')
);
```
## 查如果props未定義時,如何設定初始值
---
`var [count, setCount] = React.useState(props.count);`
這是ES6結構函式新語法,等於下面三行程式碼
```
const arr = React.useState(props.count)
const count = arr[0]
const setCount = arr[1]
```
---
### 加1計數
```
function Counter(props) {
//* // TODO
var [count, setCount] = React.useState(props.count);
const atClick =() => {
setCount(count + 1)
}
return (
<div className="counter">
<h1>Counter</h1>
<div className="count">{count}</div>
<button onClick={atClick}>+1</button>
</div>
);
// */
}
ReactDOM.render(
<div>
<Counter count={1} />
<Counter count={1} />
</div>
,
document.getElementById('app')
);
```
在JSX註冊事件:
`<button onClick={atClick}>+1</button>`
在標籤後寫上on事件={at事件},at事件是習慣寫法
在定義at事件行為
```
const at事件 =() => {
行為
}
```
---
## 例題5
```
function UserGreeting(props){
return <h1 className="user">{props.name}登入成功</h1>
}
function GuestGreeting() {
return <h1 className="guest">Please sign up.</h1>;
}
function App(){
//* // TODO
const [isLoggedIn, setLoggedIn] = React.useState(false);
const atClick = () => {
setLoggedIn(!isLoggedIn);
}
return (
<div className="app">
<button onClick={atClick}>{isLoggedIn ? '登出' : '登入'}</button>
{isLoggedIn ? <UserGreeting /> : <GuestGreeting />}
{isLoggedIn && <UserGreeting name="milkmidi" />}
</div>
)
// */
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
```
* ` const [isLoggedIn, setLoggedIn] = React.useState(false);`這裏isLoggedIn型別為布林,會跟帶入的值(false)型別相同
* && 用法為當左邊成立時,會render右邊
---
## 範例7:生命週期lifecycle 1446
```
function Clock() {
React.useEffect(() => {
console.log('componentDidMount')
return () => {
console.log('componentWillUnmount');
}
}, []);
return (
<div className="my-component">
<h2>react useEffect</h2>
</div>
)
}
```
* 跟生命週期有關的使用useEffect
* `console.log('componentDidMount')`時component誕生
* `return () => {
console.log('componentWillUnmount');}` 時component死亡
* 目前Clock的第二個參數放[],放[]有其他用途
---
## 範例8
```
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
function List(){
//* // TODO
const [list, setList] = React.useState(['學會 JS', '學會 React', '年薪百萬']);
const atAddClick = () => {
var newList = list.concat(new Date().toString());
setList(newList);
}
return (
<div>
<button onClick={atAddClick}>Add</button>
<ol className="list">
{
list.map(function (text) {
return <li key={text}>{text}</li>;
})
}
</ol>
</div>
)
// */
}
ReactDOM.render(
<List />,
document.getElementById('app')
);
```
* key是react規定使用(進階)
1318