学习React
运行React
<!DOCTYPE html>
<html>
<head>
<script src="/libs/react.development.js"></script>
<script src="/libs/react-dom.development.js"></script>
<script src="/libs/babel-standalone.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
// jsでタグは読み込まれないので、javascriptのオブジェクトに変換する際にバベルを使ってjavascriptのコードを変換して使用
const appEl = document.querySelector('#app');
const root =ReactDOM.createRoot(appEl);
root.render(<h1>こんにちは</h1>);//jsx構文
//予期せぬ文字列となっている:jsで読み込まれない。
// v18以降はroot.renderが推奨
// 下記は非推奨
// ReactDOM.render(<h1>こんにちは</h1>,appEl);
</script>
</body>
</html>
组件:
React中定义了屏幕上的每个构成要素。
・再利用能力的提升
・可读性的提升
・实现低耦合(减少错误)
组件是JS的函数定义
function Welcome(){
return <h1>Hello</h1>;
}
<Welcome />
<!DOCTYPE html>
<html>
<head>
<script src="/libs/react.development.js"></script>
<script src="/libs/react-dom.development.js"></script>
<script src="/libs/babel-standalone.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
const appEl = document.querySelector('#app');
const root = ReactDOM.createRoot(appEl);
function Example(){//必ず関数の頭は大文字、小文字だとhtmlのタグと認識される。
return <h1>Hello Components</h1>; //関数コンポーネント
}
// const Example2 =() =>{
// return <h1>Hello Components2</h1>
// }
// 1行の時
const Example2 =() => <h1>Hello Components2</h1>
//複数行の時
const Example3 =() =>{
return (
<div>
<h1>Hello Components2</h1>
</div>
)
}
//下記でもOK,{}なしでもreturn のみなので不要
const Example4 =() => (
<div>
<h1>Hello Components2</h1>
</div>
)
const a =() =>{
return //何も続けなかった場合にjavascriptエンジンが "return undefined;"のセミコロンが代入されているのと同じことになり、undefineとなり、実行文章が終えることと同じ意味になるため、改行と同じ意味になります。
// 複数行である場合には()をつけるようにする。
"戻り値";
}
console.log(a())
root.render(<Example2 />);
</script>
</body>
</html>
响应开始
# プロジェクトの作成方法
npx create-react-app {プロジェクト名}
# create-react-appドキュメント
npm docs create-react-app
Windowsの方でエラーが発生する方は以下のコマンドを実行してみてください。
```powershell
Set-ExecutionPolicy RemoteSigned
其他
使用 Vite 模块打包工具创建项目。
最近变得很常见。
npm create vite@latest
"scripts": {
"start": "react-scripts start",
//開発時に使うコマンドでサーバーを立ち上げアプリを使う
"build": "react-scripts build",
//本番環境用にビルドするコマンド
"test": "react-scripts test",
//テストスクリプトを実行するようのコマンド
"eject": "react-scripts eject"
//隠しファイルを表示する用のコマンド
},
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint src --ext js,jsx --report-unused-disable-directives --max-warnings 0",
//コードチェック
"preview": "vite preview"
},
反应样式
import "./Example.css";
class MyClass{}//<<JSでは左のように使うため。混同しないように
const Example = () => {
return (
<div className="component">
{/* classではなくclassNmae */}
<h3>Hello Component</h3>
</div>
);
};
export default Example;
.App-start .component{
padding:1rem;
color:red;
border:5px solid green
}
/* cssはグローバルになるため、CSSを当てる際には注意が必要 */
将零件分割
import Child from "./component/Child";
// .jsはどちらでも良いwebpackが勝手に解釈してくれる
import Child from "./components/Child"
const Example = () => <Child />;
export default Example;
const Child = () => {
return (
<div className="component">
<h3>Child Component</h3>
</div>
);
}
//コンポーネントは一つのファイルに一つのコンポーネントが普通
//export default でOK
export default Child
片段
import "./Child.css";
// import React from "react" //どちらでも良い
//この場合には<React.Fragment>で囲む
import { Fragment } from "react"; //どちらでも良い
const Child = () => {
return (
// ルート要素として一つのルートで囲む必要がある。
// divなど不要なタグで囲まないようにするためにFragmentを使う
//fragmentは属性をつけることができない
<Fragment key="">
{/* キー属性はつけることが可能、ただし、Fragmentのキーワードは省略不可 */}
{/* <>でOK */}
<div className="component">
<h3>Hello Component</h3>
</div>
<h3>Hello Fragment</h3>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati repellat dolor doloribus iure consequatur soluta? Optio corrupti ratione suscipit recusandae eius perspiciatis illo corporis? Aliquam nam repellendus quos expedita est?</p>
</Fragment>
);
};
export default Child;
用中文原生地重述以下的句子,只需要一个选项:
执行React的JS。
在JavaScript代码中,使用花括号来评估JavaScript代码并将结果显示在屏幕上。
import "./Expression.css"
const Expression = () => {
const title = "Expression";
const arry = ['item1', 'item2', 'item3'];
const hello = (arg) => `${arg} function`; //`${arg}`:テンプレートリテラル
const jsx = <h3>Helloe JSX</h3>;//Javascriptのオブジェクトとして使われる。
const bool = true;
return (
<div className={title.toLowerCase()}>
{/* タイトルを使って小文字表示 メソッドも実行可能*/}
<h3>Hello {title}</h3>
<h3>Hello {arry}</h3>
{/* 配列の場合自動的に展開されて表示する */}
<h3>{hello('Hello')}</h3>
<h3>{/* 画面上に表示されません。 */}</h3>
{<h3>Helloe JSX</h3>}
{/*これも JS コード 最終的にJSのオブジェクトに変換される。 */}
{bool}
{/* boolearnは表示されない。 */}
</div>
);
//jsのコードを埋め込むことができる。式を埋め込み可能
}
export default Expression;
式和文
在JSX中,只能使用表达式。表达式是可以返回某些值(可以赋值给变量)的东西。这些包括变量声明、for循环、if语句、switch语句和分号分隔的东西。
import "./Child.css";
const Child = () => {
const fn = () => 'hello';
const a =if (true) { 'hello' };//NG
// if文自体は変数に代入できないものなので文となる。
const f = fn();
//関数を実行した結果はhelloという値を返す式となりますので、この関数の実行結果は式
const c = 1 === 1;
//式 左オペランドと右オペラんどが等しい場合にはtrue/falseを返す式となります。
//ただし、表示はされない
const b = 1;
// const b = 1;は文になる。
// 1というのは1という値を返す式、変数に代入できる。
1;//式にも文にもなりえる 式ぶん
if (true) { 'hello' };
// ここでif文はOK
return (
<div className="component">
<h3>式と文</h3>
{1 === 1}
{/* 非表示い */}
{true ? 'hello' : 'bye'}
{/* OK */}
{if (true) {'hello'};}
{/* NG for も同様 return内で使わなければOK */}
</div>
);
};
export default Child;
const title = 'Expression';
const array = ['item1', 'item2', 'item3'];
const fn = (arg) => {
return `${arg} Function`;
};
const upperCaseText = 'upperCaseText';
const Example = () => {
return (
<>
<h3>Hello JSX</h3>
{/* toUpperCaseメソッドで文字列をすべて大文字にします。 */}
<h3>{upperCaseText.toUpperCase()}</h3>
{/* +演算子で文字列を結合します。 */}
<h3>{'Hello ' + title}</h3>
{/* 配列がJSX内で渡されると自動的に要素が展開されて表示されます。 */}
<h3>{array}</h3>
{/* 関数の実行はreturnに続く値が返ってきます。 */}
<h3>{fn('Hello')}</h3>
</>
);
};
export default Example;
道具
import Child from "./components/Child";
const Example = () => {
return (
<>
<Child />
<Child color="red" />
</>
)};
// 属性を指定して値を渡すことが可能
export default Example;
import "./Child.css";
// 外部から値を渡して再利用性を
// const Child = (props) => {
// propsである必要なし pでも慣習的に暗黙ルール
// 分割代入する場合
const Child = ({ color:c = 'green' }) => {
// green:初期値設定
// color:c colorの値をcとして置き換えて使う
console.log()
return (
<>
<div className={`component ${c}`}>
<h3>Hello Component</h3>
</div>
</>
);
};
export default Child;
道具2
import Child from "./components/Child";
const Example = () => {
const hello = (arg) => `ello ${arg}`;
const o = {
color: "red",
num:123,
}
return (
<>
{/* <Child /> */}
{/* <Child color="red" /> →エラー*/}
{/* 下記でfnを渡すように定義されていることから、呼び出す際にpropsとして関数を渡していないのでfnはundefinedとなり、fn is not a functionとなる */}
<Child
{...o}
// スプレッド演算子でオブジェクトの値が展開される。
// num={123}
fn={hello}
bool
obj={{ name:'Tom',age:18 }}
// trueの値が渡ってくる
/>
{/* 属性が定義されていない分についてはundefinedとなる。 */}
</>
)
};
// 属性を指定して値を渡すことが可能
export default Example;
/* POINT 式と文
式:何らかの値を返すもの(変数に代入できるもの)
文:変数宣言、for文、if文、switch文やセミコロンで区切るもの。
*/
import "./Child.css";
// 外部から値を渡して再利用性を
// const Child = (props) => {
// propsである必要なし pでも慣習的に暗黙ルール
// 分割代入する場合
// const Child = (props) => {
// console.log(props)
const Child = ({ color:c = 'green',num, fn,bool,obj }) => {
// green:初期値設定
// color:c colorの値をcとして置き換えて使う
console.log();
return (
<>
<div className={`component ${c}`}>
<h3>Hello Component</h3>
<h3>{num}</h3>
<h3>{fn('Props')}</h3>
<h3>{bool ? 'true' :'false'}</h3>
<h3>{obj.name + obj.age}</h3>
</div>
</>
);
};
export default Child;
儿童
import Profile from "./components/Profile";
import Container from "./components/Container";
const profile = [
{ name: "Takashi", age: 19, country: "Japan", color: "green" },
{ name: "Jane", age: 28, country: "UK", color: "red" },
];
const Example = () => {
return (
<div>
<Container title="Childrenとは?" >
<Profile {...profile[0]} />
</Container>
</div>
);
};
const Example2 = () => {
return (
<div>
<Container title="Childrenとは?" children={
[<Profile key={profile[0].name} {...profile[0]} />,
<Profile key={profile[1].name} {...profile[1]} />]
} first={<Profile key={profile[0].name} {...profile[0]} />}
second={<Profile key={profile[1].name} {...profile[1]} />}
/>
{/* 上記の表現でも問題なし、このコンポーネント自体もjavascriptのオブジェクトになりますので、この列に格納することができます。 */}
</div>
);
};
export default Example2;
道具的规则
// POINT props在组件间是单向传递的,从父组件到子组件。
// POINT props是只读的。
import Bye from "./components/Bye"
import Hello from "./components/Hello"
const Example = () => {
const name = "Tom";
return (
<>
<Hello name={ name } />
<Bye name={name } />
</>
);
};
export default Example;
const Hello = (props) => {
// props.name = 'BOb';// エラー読み取り専用props
const desc = Reflect.getOwnPropertyDescriptor(props, 'name');
console.log(desc);
// configurable:false;変更できるか?できない
// writable:false;書き換え可能か?不可
return (
<div>
<h3>Hello {props.name}</h3>
</div>
);
};
export default Hello;
const Bye = (props) => {
const name = 'Tom';
// Helloへは渡せない
// 親コンポーネント
return (
<div>
<h3>Bye {props.name}</h3>
</div>
);
};
export default Bye;
JSX的真正身份
在babel中,函数被替换为对象。
经过JSX语法转换,会将其转换为JS对象。
JS对象(React元素)
const sample2 = (
<div>
<h1>Hello!</h1>
<h2>Good to see you.</h2>
</div>
);
巴别塔的翻译
const sample2 =React.createElement(
"div",//タグ名
null,// プロップスの値
React.createElement("h1", null, "Hello!"),
React.createElement("h2", null, "Good to see you.")
);
执行结果
const element ={
type:'h1',
props:{
className:'greeting',
children:'Hello World'
}
};
关于用于开发的事件。
const Example = () => {
const clickHandler = () => {
alert('ボタンがクリックされrました。');
// 戻り値returnがないのでundefinedの戻り値が返ってくる。
}
// 極力名前付き関数を定義してから下記に入力
const hello = () => 'hello react';
console.log(hello)
// () => 'hello react'がそのまま表示される。
console.log(hello());
// hello reactが表示される。
return (
<>
<button onClick={clickHandler}>クリックしてね</button>
{/* onClickのCは大文字 */}
{/* clickHander()(関数を実行したもの)と()をつけるわけではなくclickHandler(ボタンを押されて実行するもの)として記載する。 */}
<button onClick={() => clickHandler()}>クリックしてね</button>
{/* 上記の場合には関数の実効記載が必要。クリックされてから関数が実行するため、実行されたreturnには()を付けないと関数が戻り値となってしまう。 */}
<button>クリックしてね</button>
{hello()}
</>
);
};
export default Example;
import "./Example.css";
const Example = () => {
return (
<div>
<h3>コンソールを確認してください。</h3>
<label>
入力値のイベント:
<input
type="text"
onInput={() => console.log("onChange検知")}
//JSにおけるonInputがReactのonChangeイベントと同じ(変更された時に発火する)ようになる
// 通常JSではonchangeイベントは入力を終えてフォーカスが外れた時に動作する。
onBlur={() => console.log("onBlur検知")}
// 入力欄からフォーカスが消えた時を検知
onFocus={() => console.log("onFocus検知")}
// 入力欄からフォーカスを得た時を検知
/>
</label>
<div>
<label>
入力値を取得:
<input type="text" onChange={(e) => console.log(e.target.value)} />
</label>
</div>
{/* マウスホバー時を検知 */}
<div
className="hover-event"
onInput={() => console.log("カーソルが入ってきました。")}
onChange={() => console.log("カーソルが入ってきました。")}
onMouseEnter={() => console.log("カーソルが入ってきました。")}
onMouseLeave={() => console.log("カーソルが出ていきました。")}
>
ホバーしてね!
</div>
</div>
);
};
export default Example;
使用useState
import { useState } from "react";
const Example = () => {
let valArry = useState("hello");
let [val, setVal] = useState('hello');
// [0,f]
//配列の0番目に参照用の値が渡ってきます。
// 配列の0番目:参照用の値
// 配列の1番目:更新用の関数
// 初期値0
// 読み込み用と
console.log(valArry)
return (
<>
<input
type="text"
onChange={(e) => {
// const setFn = valArry[1];
setVal(e.target.value)
// 更新されない
}} /> = {val}
</>
);
};
export default Example;
无论修改变量的值如何,屏幕上的显示不会改变的原因是:React需要请求重新执行(重新渲染)组件,并创建新的React元素。需要将修改的值保存在某个地方(保存在状态中)。useState是实现这些功能的机制。
import { useState } from "react";
const Example = () => {
let displayVal;
//2. Exampleが実行されるたびに値が空になってしまう。
let [ val, setVal ] = useState();
console.log('再レンダリングされました');
return (
<>
<input
type="text"
onChange={(e) => {
console.log(e.target.value);
setVal(e.target.value);
//1. displayVal = e.target.value; onChangeにおってコードが実行される
}}
/>
= {val}{/* このコードはExample()が実行されないと変わらない/3.さらにExampleが実行されると2の挙動で空が反映される。 */}
</>
);
};
export default Example;
1. 连接hook进入React内部。以便管理状态。
2. 返回当前值和更新函数。
3. 通过更新函数将新值传递给React,并请求React重新执行自身组件。
在每个组件中保持的是useState。
import { useState } from "react";
const Example = () => {
let displayVal;
//2. Exampleが実行されるたびに値が空になってしまう。
let [ val, setVal ] = useState();
console.log('再レンダリングされました');
return (
<>
<input
type="text"
onChange={(e) => {
console.log(e.target.value);
setVal(e.target.value);
//1. displayVal = e.target.value; onChangeにおってコードが実行される
}}
/>
= {val}{/* このコードはExample()が実行されないと変わらない/3.さらにExampleが実行されると2の挙動で空が反映される。 */}
</>
);
};
export default Example;
import { useState } from "react";
const Example = () => {
// let displayVal;
//2. Exampleが実行されるたびに値が空になってしまう。
let [ val, setVal ] = useState();
console.log('再レンダリングされました');
return (
<>
<input
type="text"
onChange={(e) => {
console.log(e.target.value);
// displayVal =e.target.value
setVal(e.target.value);
//1. displayVal = e.target.value; onChangeにおってコードが実行される
}}
/>
{/* = {displayVal} */}
{/* Stateを利用しないと再レンダリングされない */}
= {val}
{/* このコードはExample()が実行されないと変わらない/3.さらにExampleが実行されると2の挙動で空が反映される。 */}
</>
);
};
export default Example;```
```jsx
import { useState } from "react";
const Example = () => {
console.log(<Example />)
// _owner FiberNode
// memorizedStateにて値が保持される。
// 次の値はnextに入っている。
const [btnValA, setValA] = useState(0);
// コンポーネントのトップレベルしか呼ぶことができないuseState
// if,for,whileなど{}文内においても使用できない。
// setValAの関数と紐付けされたbtnValAが更新される
const [btnValB, setValB] = useState(10);
// 順番で定義されたもの保持されるuseState
const [ btnValC, setValC ] = useState(100);
const btnCountUp = () => {
setValA(btnValA + 1);
}
const btnCountUpB = () => {
setValB(btnValA + 1);//更新されない
}
const btnCountUpC = () => {
setValC(btnValC + 1);
}
return (
<>
<p>ボタンAを{btnValA}回押しました!</p>
<button onClick={btnCountUp}>ボタンA</button>
<p>ボタンBを{btnValB}回押しました!</p>
<button onClick={btnCountUpB}>ボタンB</button>
<p>ボタンAを{btnValC}回押しました!</p>
<button onClick={btnCountUpC}>ボタンA</button>
</>
);
};
export default Example;
import { useState } from "react";
const Example = () => {
const [count, setCount] = useState(0);
const countUp = () => {
setCount(count + 1);//:値は1//非同期処理となる。
setCount(count + 1);//:値は1
setCount(p => p + 100);//:値は101 関数の引数は前の関数の結果
setCount(p => p + 1);//:値は1
console.log(count);
}
const countDown = () => {
setCount(count - 1);
}
return (<>
<p>現在のカウント数:{count}</p>
<button onClick={(countUp)}>+</button>
<button onClick={(countDown)}>-</button>
</>);
};
export default Example;
useState的注意事项。
由于useState函数具有惰性求值的概念,
因此不会立即执行。
因此,如果要在函数执行时反映当前状态,
可以通过在set函数内部设置一个函数来引用并更新值。
import { useState } from 'react';
const Example = () => {
const [count, setCount] = useState(0);
const countUp = () => {
setCount(state => state + 1);
// 現在の値を見て行う場合が多いので常時上記の使い方で実施
};
const countDown = () => {
setCount(state => state - 1);
};
return (
<>
<h3>練習問題</h3>
<p>現在のカウント数: {count}</p>
<button onClick={countUp}>+</button>
<button onClick={countDown}>-</button>
</>
);
};
export default Example;
使用useState时需要注意的一些事项
// POINT 原始数据类型:1, “str”, bool, 10n, Symbol(), null, undefined
// POINT 对象类型:除了{},[]等原始数据类型之外的类型
// POINT 如果要更改对象类型的状态,则必须创建一个新对象!
import { useState } from "react";
const Example = () => {
const personObj = { name: "Tom", age: 18 };
const [person, setPerson] = useState(personObj);
const changeName = (e) => {
setPerson({ name: e.target.value, age: person.age });
// setPerson({ name: e.target.value, age: person.age });
// ageプロパティを消してしまうと更新されてしまうので、setPersonを実行する際には必ず同じ構造で記載すること。
}
const changeAge = (e) => {
setPerson({ name: person.name, age:e.target.value });
}
const reset = () => {
setPerson({ name: "", age: "" });
}
return (
<>
<h3>Name:{person.name}</h3>
<h3>Age:{person.age}</h3>
<input type="text" name="" onChange={changeName} id="" value={person.name} />
<input type="number" name="" onChange={changeAge} id="" value={person.age} />
<div>
<button onClick={reset}>リセット</button>
</div>
</>
);
};
export default Example;
关于对象的useState子集。
import { useState } from 'react';
const Example = () => {
const orderObj = { item: 'apple', count: 10 };
const [order, setOrder] = useState(orderObj);
const changeItem = (e) => { setOrder({ ...order, item: e.target.value }) };
// スプレッド演算子で展開
const countUp = () => {
setOrder((order) => ({ ...order, count: order.count + 1 }));
// 配列に()をつけるのは配列がオブジェクトリテラルなのか、あろー関数の関数式か不明であるため、オブジェクトを返す場合には()入れる。
};
const countDown = () => {
setOrder((order) => ({ ...order, count: order.count - 1 }));
};
return (
<div>
<h3>練習問題</h3>
<p>
記述を変更し、完成コードのように「+と-ボタンをクリックするとCountの表示が1ずつ増減する機能」と「input要素に連動してItemの表示が変更される機能」を実装してください。コンポーネントの外側(上部)に変数や関数を準備しているためうまく使ってください。
</p>
<h3>Item:{order.item}</h3>
<h3>Count:{order.count}</h3>
<input type="text" value={order.item} onChange={changeItem} />
<button onClick={countUp}>+</button>
<button onClick={countDown}>-</button>
</div>
);
};
export default Example;
useState数组
import {useState} from "react"
const Example = () => {
const numArray = [1, 2, 3, 4, 5];
const [nums, setNums] = useState(numArray);
console.log(nums);
const shuffle = () => {
const newNums = [...nums];
// スプレッド演算子として定義する。新しい配列として定義する。
// newNums =numsは配列がコピーではなく、配列の参照をコピーしている。
const value = newNums.pop();
newNums.unshift(value);
setNums(newNums);
// 配列の末尾が削除
console.log(newNums)
}
return (
<>
<h1>{nums}</h1>
{/* {}で展開されると並んで表示される。 */}
<button onClick={shuffle}>shuffle</button>
</>
);
};
export default Example;
国家
State 按照组件进行保持。
每个组件的相关值都是独立管理的。
通过React元素树中的位置来识别哪个组件的状态。
如果在React元素树的组件位置不变的情况下,状态将保持不变。
然而,通过给组件添加key属性,即使是同一位置的相同组件也能被识别为不同的实体。
import { useState } from "react";
const Example = () => {
const [toggle, setToggle] = useState(true);
const toggleComponent = () => {
setToggle(prev => !prev)
}
return (
<>
<button onClick={toggleComponent}>toggle</button>
{toggle ? <Count title="A" /> : <Count title="B" />}
{/* 上記の内容では表示位置が変わらない */}
{/* stateの値を引き継ぐ、同じ位置で切り替わる場合について */}
{toggle ? <Count title="A" /> : <div><Count title="B" /></div>}
{/* 上記の場合にはdivがBに追加されているためツリー構造が変わることから値が引き継がれない */}
<Count title="A" />
{toggle && <Count title="B" />}
{/* 上記の場合にはコンポーネントが消滅するため、値が初期化される。 */}
{toggle ? <Count key="A" title="A" /> : <Count key="B" title="B" />}
{/* 上記のコンポーネントが値を別々にしたい場合にはkeyという属性を設定することで、一意のコンポーネントの値を管理できる。 */}
</>
)
}
const Count = ({ title }) => {
const [count, setCount] = useState(0);
const countUp = () => {
setCount((prevstate) => prevstate + 1);
};
const countDown = () => {
setCount(count - 1);
};
return (
<>
<h3>{title}: {count}</h3>
<button onClick={countUp}>+</button>
<button onClick={countDown}>-</button>
</>
);
};
export default Example;
将state作为props传递的情况下
・当组件可能会消失时
・需要在多个子组件之间共享特定状态时
import { useState } from "react";
const Example = () => {
const [toggle, setToggle] = useState(true);
const [countA, setCountA] = useState(0);
const [countB, setCountB] = useState(0);
const toggleComponent = () => {
setToggle(prev => !prev);
}
return (
<>
<button onClick={toggleComponent}>toggle</button>
{/* {toggle ? <Count key="A" title="A" count={count} setCount={setCount} /> : <Count key="B" title="B" count={count} setCount={setCount} />} */}
{/* 定義したSTATEをpropsで渡す(値を共有する) */}
<Count key="A" title="A" count={countA} setCount={setCountA} />
<Count key="B" title="B" count={countB} setCount={setCountB} />
</>
)
}
const Count = ({ title,count,setCount }) => {
const countUp = () => {
setCount((prevstate) => prevstate + 1);
};
const countDown = () => {
setCount(count - 1);
};
return (
<>
<h3>{title}: {count}</h3>
<button onClick={countUp}>+</button>
<button onClick={countDown}>-</button>
</>
);
};
export default Example;
useState:用于存储值并请求重新渲染的钩子函数
在组件中调用。
在中文中不要在if语句或for循环中调用。
・值的更新和重新渲染被预约(异步进行)