DEV Community

Cover image for Giới thiệu về Immer - Phần 3
mikebui
mikebui

Posted on

Giới thiệu về Immer - Phần 3

Bài dịch từ trang chủ của Immer:
https://immerjs.github.io/immer/

Sử dụng Curried producers

Trước tiên cần hiểu về currying function.

Thay vì truyền vào cho function 1 lúc nhiều argument, chúng ta lại chuyển kiểu viết đó thành 1 function chỉ nhận 1 argument, nhưng bên trong đó chúng ta lòng các function con bên trong, và return về function con này.

Code sample

import "./styles.css";
import React from "react";

export default function App() {
  const [name, setName] = React.useState("mike");
  const handleClick = (name) => (e) => {
    if (name === "minh") {
      alert("currying function");
      console.log(e.target);
    }
  };
  return (
    <div>
      <input value={name} onChange={(e) => setName(e.target.value)} />
      <button name="button-test" onClick={handleClick(name)}>
        Click me
      </button>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

Hay ứng dụng trong validation của form. (Dự án mình dùng là vậy)

Quay lại về curried producers

Việc truyền một hàm làm đối số đầu tiên cho produce sẽ tạo ra một hàm chưa áp dụng produce cho một state cụ thể, mà tạo ra một hàm sẽ áp dụng produce cho bất kỳ state nào được truyền cho nó trong tương lai. Điều này thường được gọi là currying. Lấy ví dụ sau:

import produce from "immer"

function toggleTodo(state, id) {
    return produce(state, draft => {
        const todo = draft.find(todo => todo.id === id)
        todo.done = !todo.done
    })
}

const baseState = [
    {
        id: "JavaScript",
        title: "Learn TypeScript",
        done: true
    },
    {
        id: "Immer",
        title: "Try Immer",
        done: false
    }
]

const nextState = toggleTodo(baseState, "Immer")
Enter fullscreen mode Exit fullscreen mode

Mô hình trên của toggleTodo khá điển hình; truyền state hiện có tới produce, sửa đổi bản nháp (draft) và sau đó trả về kết quả. Vì state không được sử dụng cho bất kỳ điều gì khác ngoài việc truyền tới produce, ví dụ trên có thể được đơn giản hóa bằng cách sử dụng dạng curried của produce, trong đó bạn chỉ truyền công thức (recipe) cho produceproduce sẽ trả về một hàm mới , hàm mới này áp dụng công thức (recipe) tới baseState. Điều này cho phép chúng ta rút ngắn định nghĩa toggleTodo ở trên.

import produce from "immer"

// curried producer:
const toggleTodo = produce((draft, id) => {
    const todo = draft.find(todo => todo.id === id)
    todo.done = !todo.done
})

const baseState = [
    /* as is */
]

const nextState = toggleTodo(baseState, "Immer")
Enter fullscreen mode Exit fullscreen mode

Lưu ý rằng param id hiện đã trở thành một phần của hàm công thức (recipe)!

Top comments (0)