学习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循环中调用。

・值的更新和重新渲染被预约(异步进行)

广告
将在 10 秒后关闭
bannerAds