Как передать обработчик onClick из родительских в дочерние компоненты через необязательные аргументы с метками - PullRequest
0 голосов
/ 11 декабря 2018

Я хочу передать обработчик события в ряд компонентов от родителя к потомку.Вот рабочий пример:

Index.re

ReactDOMRe.renderToElementWithId(
  <App myHandler={_evt => Js.log("my handler clicked")} />,
  "root",
);

App.re

let component = ReasonReact.statelessComponent(__MODULE__);

let make = (~myHandler, _children) => {
  ...component,
  render: _self => <MyComponent myHandler />,
};

MyComponent.re

let component = ReasonReact.statelessComponent(__MODULE__);

let make = (~myHandler, _children) => {
  ...component,
  render: _self =>
    <div onClick=myHandler> {ReasonReact.string("click me")} </div>,
}

Как этокод теперь, аргумент myHandler требуется при каждом использовании компонента, в противном случае мы получим ошибку:

This call is missing an argument of type (~myHandler: ReactEvent.Mouse.t => unit)

Помеченные аргументы можно сделать необязательными, добавив =? в объявлении функции следующим образом:

let component = ReasonReact.statelessComponent(__MODULE__);

let make = (~myHandler=?, _children) => {
  ...component,
  render: _self =>
    <div onClick=myHandler> {ReasonReact.string("click me")} </div>,
};

Однако это приводит к ошибке компиляции:

  5 │   ...component,
  6 │   render: _self =>
  7 │     <div onClick=myHandler> {ReasonReact.string("click me")} </div>,
  8 │ };

  This has type:
    option('a)
  But somewhere wanted:
    ReactEvent.Mouse.t => unit

Я подумал, что, возможно, компилятору может понадобиться подсказка.Затем я попытался явно добавить этот тип к объявлению функции следующим образом:

let component = ReasonReact.statelessComponent(__MODULE__);

let make = (~myHandler: ReactEvent.Mouse.t => unit=?, _children) => {
  ...component,
  render: _self =>
    <div onClick=myHandler> {ReasonReact.string("click me")} </div>,
};

Но затем ошибка переворачивается на меня и дает мне:

  4 │ let make = (~myHandler: ReactEvent.Mouse.t => unit=?, _children) => {
  5 │   ...component,
  6 │   render: _self =>

  This pattern matches values of type
    ReactEvent.Mouse.t => unit
  but a pattern was expected which matches values of type
    option('a)

И теперь я всезапутался.

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

Просто чтобы дать правильный ответ, поскольку маловероятно, что он будет закрыт как дубликат

Необязательные аргументы превращаются в option s на стороне вызываемого.Иначе как бы вы представили отсутствие аргумента.Помните, что нулевых значений нет, поэтому обнуляемость должна быть выражена явно.

myHandler, следовательно, option(ReactEvent.Mouse.t => unit).onClick, конечно, также является необязательным аргументом, который будет преобразован в option, но, поскольку это, как правило, выполняется автоматически, мы не можем просто передать ему option напрямую.

К счастью,кто-то уже думал об этом сценарии и добавил синтаксическую конструкцию, чтобы иметь возможность явно передавать option s в качестве необязательных аргументов.Просто добавьте ? перед выражением, переданным в аргумент, и все будет хорошо:

<div onClick=?myHandler> {ReasonReact.string("click me")} </div>,
0 голосов
/ 12 декабря 2018

Таким образом, чтобы необязательный аргумент работал, вы должны обработать сам необязательный регистр в компоненте MyComponent.

let component = ReasonReact.statelessComponent(__MODULE__);

let make = (~myHandler=?, _children) => {
   ...component,
   render: _self => {
      let myHandler = switch myHandler {
        | None => (_e) => Js.log("default");
        | Some(handler) => handler;
   };
   <div onClick=myHandler> {ReasonReact.string("click me")} </div>
}
...