使用咖喱法向React事件处理程序传递额外数据

80 阅读1分钟

一个例子

在有些情况下,我们想向React事件处理程序传递额外的数据。考虑一下下面的例子。

const List = ({
  items,
}: {
  items: string[],
}) => {
  const handleClick = () => {
    console.log(
      "How do I get the item related to the button?"
    );
  };
  return (
    <ul>
      {items.map((item) => (
        <li key={item}>
          <span>{item}</span>
          <button onClick={handleClick}>
            Log
          </button>
        </li>
      ))}
    </ul>
  );
};

我们想把列表项的数据传递给handleClick

我们可以使用一个内联的匿名函数处理程序,调用handleClick 传递列表项。

const List = ({
  items,
}: {
  items: string[],
}) => {
  const handleClick = (item: string) => {    console.log(item);
  };
  return (
    <ul>
      {items.map((item) => (
        <li key={item}>
          <span>{item}</span>
          <button
            onClick={() => handleClick(item)}          >
            Log
          </button>
        </li>
      ))}
    </ul>
  );
};

不过有一种可以说是更好的方法,叫做currying。首先,让我们了解一下什么是currying。

什么是currying?

咖喱是一种方法,当函数一次接收一个参数时。

因此,与其说是:

const func = (a, b) => { ... }

咖喱的方法是。

const func = (a) => (b) => { ... }

一个改进的handleClick

我们可以使用咖喱式handleClick ,如下所示。

const List = ({
  items,
}: {
  items: string[],
}) => {
  const handleClick = (item: string) => () => {    console.log(item);
  };
  return (
    <ul>
      {items.map((item) => (
        <li key={item}>
          <span>{item}</span>
          <button onClick={handleClick(item)}>            Log
          </button>
        </li>
      ))}
    </ul>
  );
};

所以,点击处理程序是第二个函数。第一个函数将列表项传递给处理程序。

很好!

另一个例子

另一个例子是表单字段变化处理程序,咖喱法很有用。一般来说,我们可能有这样的东西,每个字段都有一个单独的变化处理程序。

<form onSubmit={handleSubmit}>
  <input
    type="text"
    placeholder="Enter your name"
    value={values.name}
    onChange={handleNameChange}  />
  <input
    type="text"
    placeholder="Enter your email"
    value={values.email}
    onChange={handleEmailChange}  />
  <textarea
    placeholder="Enter some notes"
    value={values.notes}
    onChange={handleNotesChange}  />
  <button type="submit">Save</button>
</form>

咖喱可以帮助我们把变化处理程序浓缩到一个处理程序中。

const handleChange = (fieldName: string) => (  e: React.ChangeEvent<    HTMLInputElement | HTMLTextAreaElement  >) => {  setValues({
    ...values,
    [fieldName]: e.currentTarget.value,
  });
};

return (
  <form onSubmit={handleSubmit}>
    <input
      type="text"
      placeholder="Enter your name"
      value={values.name}
      onChange={handleChange("name")}    />
    <input
      type="text"
      placeholder="Enter your email"
      value={values.email}
      onChange={handleChange("email")}    />
    <textarea
      placeholder="Enter some notes"
      value={values.notes}
      onChange={handleChange("notes")}    />
    <button type="submit">Save</button>
  </form>
);

变更处理程序是第二个函数。第一个函数将字段名传递给处理程序。

很好!

这些例子可以在CodeSandbox中找到:codesandbox.io/s/curry-eve…