Skip to content

Instantly share code, notes, and snippets.

@Zerim

Zerim/SignupForm.re

Last active Feb 19, 2018
Embed
What would you like to do?
A simple SignupForm written in ReasonML
/* `action` and `state` types must be defined before the `let component` statement for type inference to work */
type action =
| UpdateEmail string
| UpdatePassword string;
type state = {
email: string,
password: string
};
/* Wrap the variant constructor in function so they may be composed */
let updateEmail email => UpdateEmail email;
let updatePassword password => UpdatePassword password;
let component = ReasonReact.reducerComponent "Signup";
/* Or could destructure here (i.e. `let handleSubmit _ {ReasonReact.state} => Js.log state`) */
let handleSubmit _ self => Js.log self.ReasonReact.state;
let getEventTargetValue event :string => (
ReactDOMRe.domElementToObj (
ReactEventRe.Form.target event
)
)##value;
let make _children => {
...component,
initialState: fun () => {email: "", password: ""},
reducer: fun action state =>
switch action {
| UpdateEmail value => ReasonReact.Update {...state, email: value}
| UpdatePassword value => ReasonReact.Update {...state, password: value}
},
render: fun self =>
<div className="Login">
<div> <h2> (ReasonReact.stringToElement "Signup here") </h2> </div>
/* Call self.handle to access the latest value of `self.ReasonReact.state` in the callback. */
<form onSubmit=(self.handle handleSubmit)>
<input
onChange=(
self.ReasonReact.reduce (fun event => event |> getEventTargetValue |> updateEmail)
)
placeholder="email"
/>
<input
onChange=(self.reduce (fun event => event |> getEventTargetValue |> updatePassword))
placeholder="password"
/>
<input _type="submit" value="Register" />
</form>
</div>
};
@Zerim

This comment has been minimized.

Copy link
Owner Author

@Zerim Zerim commented Sep 22, 2017

Right now, the onSubmit just does a simple console.log for testing purposes, but in theory could be used for any side-effect. Any pointers to make this example more idiomatic would be appreciated!

@Zerim

This comment has been minimized.

Copy link
Owner Author

@Zerim Zerim commented Sep 22, 2017

I know one things that could be made more concise is having a UpdatePassword and UpdateEmail actions instead of having separate variants for the field type.

@yawaramin

This comment has been minimized.

Copy link

@yawaramin yawaramin commented Sep 22, 2017

Looks great! Off the top of my head, you can design the form submit handler to be a bit more concise:

let handleSubmit state _ => Js.log state;
/* or let handleSubmit state _event => ... */
...
<form onSubmit=(handleSubmit self.state)>
@rickyvetter

This comment has been minimized.

Copy link

@rickyvetter rickyvetter commented Sep 22, 2017

handleSubmit self.state will give you the state when the component was rendered - not necessarily the state when the button is clicked (guaranteed latest). If you want that you should use onSubmit=(self.handle handleSubmit) which will provide most up-to-date state and the form to handleSubmit.

@Zerim

This comment has been minimized.

Copy link
Owner Author

@Zerim Zerim commented Sep 23, 2017

Thanks for the feedback @yawaramin and @rickyvetter! Edits made.

I couldn't easily figure out how I should be typing self in the handleSubmit function by inspection (I used ReasonReact.self _ _ _). Is that idiomatic or should I be putting something else there? Seemed to compile/work okay...

Also I was wondering if you though the onChange callback could be made more concise through functional composition/ currying, but wasn't sure if that worked for Variant constructors.

@Zerim

This comment has been minimized.

Copy link
Owner Author

@Zerim Zerim commented Sep 23, 2017

Was thinking something like: onChange=(self.ReasonReact.reduce (compose UpdateEmail getEventTargetValue))

@rickyvetter

This comment has been minimized.

Copy link

@rickyvetter rickyvetter commented Sep 25, 2017

@Zerim - I'd use either of
let handleSubmit _ self => Js.log self.ReasonReact.state; or
let handleSubmit _ {ReasonReact.state} => Js.log state;
depending on actual usecase. You can explicitly type if you'd like, but self does have a lot of baggage to carry around.

@Zerim

This comment has been minimized.

Copy link
Owner Author

@Zerim Zerim commented Sep 25, 2017

Thanks @rickyvetter, forgot I could rely on type inference instead of explicitly annotating there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.