本系列文以製作專案為主軸,紀錄小弟學習React以及GrahQL的過程。主要是記下重點步驟以及我覺得需要記憶的部分,有覺得不明確的地方還請留言多多指教。
雖然有了Components產生畫面,不過總不能一直顯示一樣的東西,而是該根據傳遞的數據更新顯示,在React中,主要的資料流藉由State、Props來產生與傳遞。
這邊只介紹function component中props與state的用法,不包含class component的部分,不過差異只在於怎麼表達,基本觀念是一致的。
JSX中帶入Components時可以加上屬性:
const element = <Welcome name="Sara" />;
這些屬性就會作為props物件傳遞,可以在Component中讀取:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
除了字串,可以用 { } 代入任何javascript變數:
const name = "Sara"
const element = <Welcome name={name}/>;
其實不只變數,只要是javascript表達式都可以:
<MyComponent foo={1 + 2 + 3 + 4} /> //props.foo = 10
可以用樣板字串:
const name = "Sara"
const element = <Welcome greetings={`Hello ${name}!`}/>;
function也可以:
const sayHi = ()=>{
console.log("Hi!")
}
const element = <Welcome sayHi={sayHi}/>;
或是
const element = <Welcome
sayHi={()=>{
console.log("Hi!")
}}
/>;
可以用javascript物件去理解,比較方便:
const name = "Sara";
const props = {
foo: 1 + 2 + 3 + 4,
name: name,
greetings: `Hello ,${name}`,
sayHi: () => {
console.log("Hi!");
},
};
很多ES6的新功能可以幫助精簡props的表達:
const props = {
foo: 1 + 2 + 3 + 4,
name: name,
};
//把想要傳遞的東西打包起來,用展開運算子一口氣帶入。
const element = <Welcome {...props}/>;
function Welcome({foo,name}) { //const {foo,name} = props
return <h1>Hello, {name}</h1>;
}
一般是用props帶入在用props.name存取值,不過一開始用解構賦值把變數拉出來,就可以直接使用了。
要注意變數跟key名稱必須一致。
const name = "Sara"
const element = <Welcome name/>; //name ={name}
省略賦值的時候若有同名的變數,就會帶入該變數。
注意如果沒有同名的變數,預設賦值 true。
反過來說若想賦值 true 可以用省略賦值的方式達成,不過不建議這麼做,哪天加了個同名的變數就亂了。
數據做為props傳進component後,不應該在components中變更prop,像是
function Welcome(props) {
props.name = "Lara"; //你不該這麼做
return <h1>Hello, {props.name}</h1>;
}
像上面的做法並不符合React更新畫面的機制,React更新畫面的主要方式來自於變更State。
在function中要使用state的話要透過useState這個hook
import React, { useState } from 'react';
function Example() {
// 宣告一個新的 state 變數,我們稱作為「count」。
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
跟props一樣,不可以直接對state做變更(immutable):
<button onClick={() => (count + 1)}> //你不該這麼做
這麼做並不會觸發更新,不過用useState宣告每個state的時候都會同時產生對應的更新方法,像是setCount。
<button onClick={() => setCount(count + 1)}>
使用像setCount這類更新state的方法時,除了更新state值外還會發出通知,說有state被更新了,這時候React就會執行render,把更新的部分反映到畫面上。
回到上面props唯讀的問題,那props的值該怎麼更新?
props是從上游傳遞而來,像是把state作為prop傳遞給component,如果希望在子元件中更新這個值的話,就要把更新方法一起傳給子元件:
function Example() {
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<CountButton count setCount /> //一起傳遞值與他的更新方法
</div>
);
}
就能在子元件中達成更新的功能:
function CountButton({ count ,setCount}) {
return <button onClick={() => setCount(count + 1)}>Click me</button>;
}
總之想更新畫面只能經過State與他的更新方法。
而呼叫setState這類方法的時機不外乎處理onclick這類事件的時候。
React中事件處理的邏輯跟一般html沒有多大不同,但是語法上有差異。
html:
<button onclick="activateLasers()">
Activate Lasers
</button>
JSX:
<button onClick={activateLasers}>
Activate Lasers
</button>
看出差別了嗎?
完整版範例:
function ActionLink() {
function handleClick(e) {
e.preventDefault();
console.log('The link was clicked.');
}
return (
<a href="#" onClick={handleClick}>
Click me
</a>
);
}
handleClick(e)中的 e 是 React特製的 synthetic event,主要是將原生event打包確保跨瀏覽器運作一致,一般使用上沒有大不同,筆記一些常用用法:
走完React簡介終於要來創專案啦。