如何通过可选的标记参数将 onClick 处理程序从父组件传递到子组件
How to pass onClick handler from parent to child components through optional labeled arguments
我想将事件处理程序从父级传递给子级的一系列组件。这是一个工作示例:
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)
现在我很困惑。
因此,要使可选参数起作用,您必须在 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>
}
只是为了提供一个正确的答案,因为这似乎不太可能作为重复关闭
可选参数在被调用方方面变成了option
。否则,您将如何表示没有论点。请记住,没有空值,因此必须明确表达可空性。
myHandler
因此是 option(ReactEvent.Mouse.t => unit)
。 onClick
当然也是一个可选参数,它将被转换为 option
,但由于这是通常自动完成的,我们不能直接将 option
提供给它。
幸运的是,有人已经想到了这种情况并添加了一个语法结构,以便能够将 option
作为可选参数显式传递。只需在传递给参数的表达式前添加一个 ?
,你应该就可以了:
<div onClick=?myHandler> {ReasonReact.string("click me")} </div>,
我想将事件处理程序从父级传递给子级的一系列组件。这是一个工作示例:
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)
现在我很困惑。
因此,要使可选参数起作用,您必须在 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>
}
只是为了提供一个正确的答案,因为这似乎不太可能作为重复关闭
可选参数在被调用方方面变成了option
。否则,您将如何表示没有论点。请记住,没有空值,因此必须明确表达可空性。
myHandler
因此是 option(ReactEvent.Mouse.t => unit)
。 onClick
当然也是一个可选参数,它将被转换为 option
,但由于这是通常自动完成的,我们不能直接将 option
提供给它。
幸运的是,有人已经想到了这种情况并添加了一个语法结构,以便能够将 option
作为可选参数显式传递。只需在传递给参数的表达式前添加一个 ?
,你应该就可以了:
<div onClick=?myHandler> {ReasonReact.string("click me")} </div>,