Is it possible to use reduce in a callback function?

195 views Asked by At

I have this simple component

let component = ReasonReact.statelessComponent("Input");

let make = (~name, ~onChange, ~value, _children) => {
    ...component,
    render: (_self) =>
        <input
            name=name
            onChange={(_) => {
              onChange(name, "change")
            }}
            value=value />
};

and I'm trying to use it like this

<Input
    name="
    placeholder="Your email"
    onChange={self.reduce((name, value) => Change(name, value))}
    label=""
    value={self.state.email} />

But I get this error on the onChange line

This is:
    ReasonReact.Callback.t(string) (defined as (string) => unit)
  But somewhere wanted:
    (string, string) => unit

  The incompatible parts:
    unit
    vs
    (string) => unit

I think I understand the error, but I have no idea to to fix it. I also to define onChange like this

onChange={(name, value) => self.reduce((_, _) => Change(name, value))}

but this time I get

This is:
    ReasonReact.Callback.t('a) (defined as ('a) => unit)
  But somewhere wanted:
    unit

Do you have an idea how to fix it ? Is it possible to call reduce inside another callback function ?

1

There are 1 answers

0
glennsl On BEST ANSWER

reduce takes a 1-ary function and returns a 1-ary function, but your onChange is expected to be a 2-ary function. Since you seem to control both sides of this, the simplest fix is to just use a tuple:

Definition:

onChange={self.reduce(((name, value)) => Change(name, value))}

Application:

onChange={(_) => {
  onChange((name, "change"))
}}

Alternatively, if you don't control how the callback is used, you can wrap it in another function like you tried to, but since reduce returns a function you have to explicitly call it:

onChange={(name, value) => self.reduce(() => Change(name, value))()}

Note: The argument you pass to the callback returned by reduce is the same argument that will be passed to the callback passed to reduce, in this case just (). But value => self.reduce(val => Action(val))(value) is therefore equivalent to just doing self.reduce(val => Action(val)).