Tips & Tricks trong ReactJS dành cho lập trình viên Frontend - Phần 1

Tips & Tricks trong ReactJS dành cho lập trình viên Frontend - Phần 1

Front-end

Cho dù bạn là người mới bắt đầu hay đã là người đã có kinh nghiệm, hướng dẫn này cung cấp những thông tin hữu ích để cải thiện kỹ năng và hiệu quả làm việc của bạn với ReactJS.

ReactJS, một thư viện JavaScript phổ biến để xây dựng giao diện người dùng, là một điều cần biết cho bất kỳ lập trình viên frontend nào. Dù bạn mới bắt đầu hay đang tìm cách nâng cao kỹ năng của mình, việc hiểu rõ React có thể cải thiện đáng kể cách làm việc của bạn với React.

Sử dụng thẻ tự đóng (self-closing)

Sử dụng thẻ tự đóng để giữ code của bạn luôn gọn gàng, tránh phức tạp.

// ❌ Tệ: quá dài dòng
<MyComponent></MyComponent>

// ✅ Tốt
<MyComponent/>

Bạn chỉ nên sử dụng đóng mở thẻ khi có 1 props children được truyền vào.

Ưu tiên sử dụng fragments thay vì các thẻ DOM

Trong React, mỗi component phải trả về một phần tử duy nhất. Thay vì gom nhóm phần tử trong một thẻ <div> hoặc <span>, hãy sử dụng <Fragment> để giữ cho DOM của bạn gọn gàng hơn, tránh DOM nodes quá nhiều.

// ❌ Tệ
function Layout() {
  return (
    <div>
      <Header />
      <Main />
      <Footer/>
    </div>
  );
}

// ✅ Tốt
function Layout() {
  return (
    <Fragment>
      <Header />
      <Main />
      <Footer/>
    </Fragment>
  );
}

Nên sử dụng cú pháp rút gọn của fragment <></>

Ngoài thẻ <Fragment>, nó còn có cú pháp rút gọn là <></>. Bạn chỉ sử dụng <Fragment> khi duyệt mảng cần có key để phân biệt.

// ❌ Tệ: Code dài dòng, không cần thiết
<Fragment>
   <ComponentA />
   <ComponentB />
</Fragment>

// ✅ Tốt
<>
   <ComponentA />
   <ComponentB />
</>

Chỉ nên sử dụng Fragment khi bắt buộc cần key.

function List({ users }) {
  return (
    <div>
      {users.map((user) => (
        <Fragment key={user.id}>
          <span>{user.name}</span>
          <span>{user.occupation}</span>
        </Fragment>
      ))}
    </div>
  );
}

Nên truyền props dạng spreading {a,b,c, ...rest}

// ❌ Tệ: Code ở bên dưới khó để đọc, không biết trong props gồm những gì
function TodoList(props) {
  return (
    <div>
      {props.todos.map((todo) => (
        <div key={todo}>
          <button
            onClick={() => props.onSelectTodo(todo)}
            style={{
              backgroundColor: todo === props.selectedTodo ? "gold" : undefined,
            }}
          >
            <span>{todo}</span>
          </button>
        </div>
      ))}
    </div>
  );
}

// ✅ Tốt: Code dưới đây trực quan, dễ hiểu hơn
function TodoList({ todos, selectedTodo, onSelectTodo }) {
  return (
    <div>
      {todos.map((todo) => (
        <div key={todo}>
          <button
            onClick={() => onSelectTodo(todo)}
            style={{
              backgroundColor: todo === selectedTodo ? "gold" : undefined,
            }}
          >
            <span>{todo}</span>
          </button>
        </div>
      ))}
    </div>
  );
}

Gán giá trị mặc định khi destructuring

// ❌ Tệ
function Button({ onClick, text, small, colorScheme }) {
  let scheme = colorScheme || "light";
  let isSmall = small || false;
  return (
    <button
      onClick={onClick}
      style={{
        color: scheme === "dark" ? "white" : "black",
        fontSize: isSmall ? "12px" : "16px",
      }}
    >
      {text ?? "Click here"}
    </button>
  );
}

// ✅ Tốt
function Button({
  onClick,
  text = "Click here",
  small = false,
  colorScheme = "light",
}) {
  return (
    <button
      onClick={onClick}
      style={{
        color: colorScheme === "dark" ? "white" : "black",
        fontSize: small ? "12px" : "16px",
      }}
    >
      {text}
    </button>
  );
}

Không nên sử dụng dấu { } khi truyền kiểu string

// ❌ Tệ: dấu ngoặc nhọn ở đây không cần thiết
<Button text={"Click me"} colorScheme={"dark"} />

// ✅ Tốt
<Button text="Click me" colorScheme="dark" />

Sử dụng kiểu boolean để kiểm tra hiển thị kết quả

Hãy đảm bảo giá trị đó là kiểu boolean trước khi sử dụng value && <Component {...props}/> để tránh hiển thị các giá trị không mong muốn trên giao diện.

// ❌ Tệ: Khi danh sách trống, số 0 sẽ được in trên màn hình
export function ListWrapper({ items, selectedItem, setSelectedItem }) {
  return (
    <div className="list">
      {items.length && ( // `0` if the list is empty
        <List
          items={items}
          onSelectItem={setSelectedItem}
          selectedItem={selectedItem}
        />
      )}
    </div>
  );
}

// ✅ Tốt
export function ListWrapper({ items, selectedItem, setSelectedItem }) {
  return (
    <div className="list">
      {items.length > 0 && (
        <List
          items={items}
          onSelectItem={setSelectedItem}
          selectedItem={selectedItem}
        />
      )}
    </div>
  );
}

Xây dựng các hàm để sử dụng lại logic

// ❌ Tệ: Logic cập nhật được lặp đi lặp lại
function Form() {
  const [{ name, email }, setFormState] = useState({
    name: "",
    email: "",
  });

  return (
    <>
      <h1>Class Registration Form</h1>
      <form>
        <label>
          Name:{" "}
          <input
            type="text"
            value={name}
            onChange={(evt) =>
              setFormState((formState) => ({
                ...formState,
                name: evt.target.value,
              }))
            }
          />
        </label>
        <label>
          Email:{" "}
          <input
            type="email"
            value={email}
            onChange={(evt) =>
              setFormState((formState) => ({
                ...formState,
                email: evt.target.value,
              }))
            }
          />
        </label>
      </form>
    </>
  );
}

// ✅ Tốt: tạo hàm createFormValueChangeHandler trả về cách xử lý chính xác cho từng field
function Form() {
  const [{ name, email }, setFormState] = useState({
    name: "",
    email: "",
  });

  const createFormValueChangeHandler = (field) => {
    return (event) => {
      setFormState((formState) => ({
        ...formState,
        [field]: event.target.value,
      }));
    };
  };

  return (
    <>
      <h1>Class Registration Form</h1>
      <form>
        <label>
          Name:{" "}
          <input
            type="text"
            value={name}
            onChange={createFormValueChangeHandler("name")}
          />
        </label>
        <label>
          Email:{" "}
          <input
            type="email"
            value={email}
            onChange={createFormValueChangeHandler("email")}
          />
        </label>
      </form>
    </>
  );
}

Chuyển dữ liệu để không phụ thuộc vào props/state của component (clean code hơn)

// ❌ Tệ: OPTIONS và renderOption không nhất thiết nằm bên trong component bởi vì chúng không phụ thuộc vào props hoặc state
function CoursesSelector() {
  const OPTIONS = ["Maths", "Literature", "History"];
  const renderOption = (option: string) => {
    return <option>{option}</option>;
  };

  return (
    <select>
      {OPTIONS.map((opt) => (
        <Fragment key={opt}>{renderOption(opt)}</Fragment>
      ))}
    </select>
  );
}

// ✅ Tốt: Di chuyển chúng ra khỏi component để component được clean
const OPTIONS = ["Maths", "Literature", "History"];

function CoursesSelector() {
  return (
    <select>
      {OPTIONS.map((opt) => (
        <option key={opt}>{opt}</option>
      ))}
    </select>
  );
}

Tổng kết

ReactJS là một thư viện mạnh mẽ có thể nâng cao đáng kể kỹ năng phát triển frontend của bạn. Tham khảo các mẹo và thủ thuật, bạn sẽ tối ưu được ứng dụng hiệu quả và hiệu suất được cao hơn.

Nguồn: https://dev.to/_ndeyefatoudiop/101-react-tips-tricks-for-beginners-to-experts-4m11