LoginSignup
0
0

More than 1 year has passed since last update.

Reactのコードを簡潔に書くためのTips7選

Last updated at Posted at 2022-08-06

新しい状態が前の状態に依存する時の更新に気をつける

新しい状態が前の状態に依存している場合は、常に前の状態の関数として状態を設定することをお勧めします。 状態の更新は非同期処理のため、バッチ処理される可能性があり、この方法で更新を書き込まないと、予期しない結果が生じる可能性があります。

BadExample

import React, { useState } from "react";
export const App = () => {
  const [isDisabled, setIsDisabled] = useState(false);
  const toggleButton = () => {
    setIsDisabled(!isDisabled);
  };
  // here toggling twice will yeild the same result
  // as toggling once
  const toggleButtonTwice = () => {
    toggleButton();
    toggleButton();
  };
  return (
    <div>
      <button disabled={isDisabled}>
        I'm {isDisabled ? "disabled" : "enabled"}
      </button>
      <button onClick={toggleButton}>
        Toggle button state
      </button>
      <button onClick={toggleButtonTwice}>
        Toggle button state 2 times
      </button>
    </div>
  );
};

GoodExample

import React, { useState } from "react";
export const App = () => {
  const [isDisabled, setIsDisabled] = useState(false);
  const toggleButton = () => {
    setIsDisabled((isDisabled) => !isDisabled);
  };
  const toggleButtonTwice = () => {
    toggleButton();
    toggleButton();
  };
  return (
    <div>
      <button disabled={isDisabled}>
        I'm {isDisabled ? "disabled" : "enabled"}
      </button>
      <button onClick={toggleButton}>
        Toggle button state
      </button>
      <button onClick={toggleButtonTwice}>
        Toggle button state 2 times
      </button>
    </div>
  );
};

コンポーネントをきれいに見やすくする

BadExample

// src/App.tsx
export default function App() {
  const posts = [
    {
      id: 1,
      title: "How to write clean react code",
    },
    {
      id: 2,
      title: "Eat, sleep, code, repeat",
    },
  ];
  return (
    <main>
      <nav>
        <h1>App</h1>
      </nav>
      <ul>
        {posts.map((post) => (
          <li key={post.id}>
            {post.title}
          </li>
        ))}
      </ul>
    </main>
  );
}

GoodExample

// src/App.tsx
export default function App() {
  return (
    <main>
      <Navigation title="App" />
      <Posts />
    </main>
  );
}
// src/components/Navigation.tsx
type NavigationProps {
  title: string;
}
export default function Navigation({ title }: NavigationProps) {
  return (
    <nav>
      <h1>{title}</h1>
    </nav>
  );
}
// src/components/Posts.tsx
export default function Posts() {
  const posts = [
    {
      id: 1,
      title: "How to write clean react code",
    },
    {
      id: 2,
      title: "Eat, sleep, code, repeat",
    },
  ];
  return (
    <ul>
      {posts.map((post) => (
        <Post key={post.id} title={post.title} />
      ))}
    </ul>
  );
}
// src/components/Post.tsx
type PostProps {
  title: string;
}
export default function Post({ title }: PostProps) {
  return <li>{title}</li>;
}

複数の状態を持つものは定数や列挙型を使う

BadExample

import React, { useState } from "react";
export const App = () => {
  const [status, setStatus] = useState("Pending");
  return (
    <div>
      <p>{status}</p>
      <button onClick={() => setStatus("Pending")}>
        Pending
      </button>
      <button onClick={() => setStatus("Success")}>
        Success
      </button>
      <button onClick={() => setStatus("Error")}>
        Error
      </button>
    </div>
  );
};

GoodExample

import React, { useState } from "react";
enum Status {
  Pending = "Pending",
  Success = "Success",
  Error = "Error",
}
// OR
// const Status = {
//   Pending: "Pending",
//   Success: "Success",
//   Error: "Error",
// } as const;
export const App = () => {
  const [status, setStatus] = useState(Status.Pending);
  return (
    <div>
      <p>{status}</p>
      <button onClick={() => setStatus(Status.Pending)}>
        Pending
      </button>
      <button onClick={() => setStatus(Status.Success)}>
        Success
      </button>
      <button onClick={() => setStatus(Status.Error)}>
        Error
      </button>
    </div>
  );
};

できるだけTSXの中を簡潔にする

BadExample

const App = () => {
  return (
    <div>
      <button
        onClick={() => {
          // ...
        }}
      >
        Toggle Dark Mode
      </button>
    </div>
  );
};

GoodExample

const App = () => {
  const handleDarkModeToggle = () => {
    // ...
  };
  return (
    <div>
      <button onClick={handleDarkModeToggle}>
        Toggle Dark Mode
      </button>
    </div>
  );
};

省略記法を使う

BadExample

type TextFieldProps {
  fullWidth: boolean;
}
const TextField = ({ fullWidth }: TextFieldProps) => {
  // ...
};
const App = () => {
  return <TextField fullWidth={true} />;
};

GoodExample

type TextFieldProps {
  fullWidth: boolean;
}
const TextField = ({ fullWidth }: TextFieldProps) => {
  // ...
};
const App = () => {
  return <TextField fullWidth />;
};

string型のpropsに波括弧は不要

BadExample

type AvatarProps {
  username: string;
}
const Avatar = ({ username }: AvatarProps) => {
  // ...
};
const Profile = () => {
  return <Avatar username={"John Wick"} />;
};

GoodExample

type AvatarProps {
  username: string;
}
const Avatar = ({ username }: AvatarProps) => {
  // ...
};
const Profile = () => {
  return <Avatar username="John Wick" />;
};

不必要なindexは使用しない

BadExample

{todos.map((todo, index) =>
  <Todo
    {...todo}
    key={index}
  />
)}

GoodExample

{todos.map(todo => (
  <Todo
    {...todo}
    key={todo.id}
  />
))}

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0