這次要建立互動的功能,讓我們動作可以很快在 .js
檔案中運作,並且轉譯(render,之前叫做「渲染」,感覺「轉譯」比較合理,先以「轉譯」為主)到畫面。
目標做到按下按鈕,可以讓畫面的數字增加,達到每次按鈕數字都會增加 1
。
.jsx
建立一份我們要轉譯的樣式,有著標題、按鈕以及計數器。因此我們有個 times
記錄點擊的次數,以及建立一個 button
物件。
function Counter() {
let times = 0; //計算次數
return (
<div id="counters">
<h1>This is a counter!</h1>
<div>
<button
onClick={() => {
console.log(`times-before: ${times}`);
times++;
console.log(`times-finished: ${times}`);
}}
>
按我
</button>
</div>
<div>times: {times}</div>
</div>
);
}
export default Counter;
從上列程式碼中,建立用 let
建立一個可改變的 times
的變數;並用 console.log
顯示變動的內容。其中,使用「`」符號把要用的字串放進去,這時可以把用「$」錢字符號和大括號組「{}」把變數放進去,就不用改冗長的組合字串。
所以執行後,會成這樣:
點擊按鈕後,雖然數值 times
有改變,但是卻不會反映在頁面上,這時需要 useState
的方式解決。
因為對於 React 而言,資料的狀態(status)沒有改變,所以需要通知 React 說「我們有改變值喔!」因此我們需要使用 useState
進行告知。
在使用 useState
前,需要把資料放入檔案中:
import { useState } from "react";
需要定義好我們要的參數,並且給他一個預設值為「0」,並且提供一個告知值被更動的功能-setTime
:
let [times_2, setTime] = useState(0); //計算次數
之後的運算邏輯一樣,就是用「++」方式增加數值,不過需要一個通知,也就是需要呼叫剛剛命名的 setTime
,所以需要增加這句:
setTime(times_2);
結合這兩個計數器後,就會變成這樣(保留之前的是用來比較有加上 useState
的差異)(檔案:Counter.js
):
import { useState } from "react";
function Counter() {
let times = 0; //計算次數
let [times_2, setTime] = useState(0); //計算次數
return (
<div id="counters">
<h1>This is a counter!</h1>
<div>
<button
onClick={() => {
console.log(`times-before: ${times} and ${times_2}`);
times++;
times_2++;
console.log(`times-finished: ${times} and ${times_2}`);
setTime(times_2);
}}
>
按我
</button>
</div>
<div>times: {times}</div>
<div>times2: {times_2}</div>
</div>
);
}
export default Counter;
這樣就大功告成囉!
index.js
最後修改作為入口的 .js
的程式碼,不僅僅是使用這個
component,也修改用另一種的轉譯方法:
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Counter />);
在這邊沒有使用先前運用的 React.StrictMode
:
root.render(
<React.StrictMode>
<Counter />
</React.StrictMode>,
);
差別在於, React.StrictMode
會提供更為嚴謹的模式檢查程式碼。在這篇文章〈What is StrictMode in React?〉提到 Strict Mode 可以更嚴謹的讀程式碼,協助我們處理程式碼中一些如沒有用到的參數、提供錯誤訊息、判斷是否有衍生問題等等
更多資料可以參考官網-Strict Mode說明 Strict Mode 的好處:
- Identifying components with unsafe lifecycles
- Warning about legacy string ref API usage
- Warning about deprecated findDOMNode usage
- Detecting unexpected side effects
- Detecting legacy context API
- Ensuring reusable state
最後結果就會這樣,有一個不會變,一個會變:
終於可以讓他動了,原來 React 有使用狀態的特性,看來運用這種特性可以保護資料,讓資料可以更為清楚哪些會變動、哪些不會。實際上更多的運用仍需繼續體驗,這就讓我們繼續看下去,可以做到多少事情吧!