React学習メモ

ちょっとした学習コードをメモします。

## useState
```
import { useState } from "react";

export default function InputForm() {
  const [person, setPerson] = useState({
    nickname: "sakamoto",
    email: "sakamoto@gmail.com",
  });

  function handlePersonNicknameChange(e) {
    setPerson({
      ...person,
      nickname: e.target.value,
    });
  }

  function handlePersonEmailChange(e) {
    setPerson({
      ...person,
      email: e.target.value,
    });
  }

  return (
    <>
      <div>
        <label>
          nickname:
          <input
            value={person.nickname}
            onChange={handlePersonNicknameChange}
          />
        </label>
      </div>
      <div>
        <label>
          email:
          <input value={person.email} onChange={handlePersonEmailChange} />
        </label>
      </div>
      <div>
        Contact me:
        <span>
          {person.nickname} {person.email}
        </span>
      </div>
    </>
  );
}

```

## Rendering Lists with useState
```
import { useState } from "react";

let userId = 0;

export default function AddUserList() {
  const [userName, setUserName] = useState("");
  const [userList, setUserList] = useState([]);

  return (
    <>
      <div>
        <input value={userName} onChange={(e) => setUserName(e.target.value)} />
        <button
          onClick={() =>
            setUserList([
              ...userList,
              {
                userId: userId++,
                userName: userName,
              },
            ])
          }
        >
          追加
        </button>
      </div>
      <div>
        <div>ユーザ一覧：</div>
        <ul>
          {userList.map((user) => (
            <li key={user.userId}>{user.userName}</li>
          ))}
        </ul>
      </div>
    </>
  );
}

```

## ショッピングカートの商品を更新
```
import { useState } from "react";

const initialProducts = [
  {
    id: 1,
    name: "Sushi",
    count: 0,
  },
  {
    id: 2,
    name: "Udon",
    count: 0,
  },
  {
    id: 3,
    name: "Ramen",
    count: 0,
  },
];

export default function ShoppingCart() {
  const [productList, setProductList] = useState(initialProducts);

  function AddItemToCart(productId) {
    setProductList(
      productList.map((product) => {
        if (product.id === productId) {
          return {
            ...product,
            count: product.count + 1,
          };
        } else {
          return product;
        }
      })
    );
  }

  return (
    <>
      <ul>
        {productList.map((product) => (
          <li key={product.id}>
            <span>
              {product.name} ({product.count}){" "}
            </span>
            <span>
              <button onClick={() => AddItemToCart(product.id)}>＋</button>
            </span>
          </li>
        ))}
      </ul>
    </>
  );
}
```

## ショッピングカートから商品を削除
```
import { useState } from "react";

const initialProducts = [
  {
    id: 1,
    name: "Sushi",
    count: 1,
  },
  {
    id: 2,
    name: "Udon",
    count: 1,
  },
  {
    id: 3,
    name: "Ramen",
    count: 1,
  },
];

export default function ShoppingCart() {
  const [productList, setProductList] = useState(initialProducts);

  function AddItemToCart(productId) {
    setProductList(
      productList.map((product) => {
        if (product.id === productId) {
          return {
            ...product,
            count: product.count + 1,
          };
        } else {
          return product;
        }
      })
    );
  }

  function removeItemFromCart(productId) {
    let newProductList = productList.map((product) => {
      if (product.id === productId) {
        return {
          ...product,
          count: product.count - 1,
        };
      } else {
        return product;
      }
    });

    newProductList = newProductList.filter((product) => product.count > 0);

    setProductList(newProductList);
  }

  return (
    <>
      <ul>
        {productList.map((product) => (
          <li key={product.id}>
            <span>
              {product.name} ({product.count}){" "}
            </span>
            <span>
              <button onClick={() => AddItemToCart(product.id)}>＋</button>
              <button onClick={() => removeItemFromCart(product.id)}>ー</button>
            </span>
          </li>
        ))}
      </ul>
    </>
  );
}

```

## useStateの代わりにImmer利用

準備
```
npm install use-immer
```

```
import { useImmer } from "use-immer";

export default function Personnel() {
  const [person, setPerson] = useImmer({
    name: "Sakamoto",
    work: {
      company: "Excite",
    },
  });

  function handlePersonNameChange(e) {
    setPerson((draft) => {
      draft.name = e.target.value;
    });
  }

  function handlePersonWorkCompany(e) {
    setPerson((draft) => {
      draft.work.company = e.target.value;
    });
  }

  return (
    <>
      <div>
        <label>
          Person:
          <input value={person.name} onChange={handlePersonNameChange} />
        </label>
        <label>
          Company:
          <input
            value={person.work.company}
            onChange={handlePersonWorkCompany}
          />
        </label>
      </div>
      <div>
        {person.name} is working for {person.work.company} now
      </div>
    </>
  );
}

```

## useReducer
```
import { useReducer } from "react";

function reducer(state, action) {
  if ((action.type = "increment")) {
    return {
      ...state,
      age: state.age + 1,
    };
  }
}

export default function Counter() {
  const [state, dispatch] = useReducer(reducer, {
    age: 0,
  });

  return (
    <>
      <button onClick={() => dispatch({ type: "increment" })}>
        Click here to increase age
      </button>
      <div>You Age is {state.age}</div>
    </>
  );
}

```