How to reset react file input

I want to reset the file input, and I try to use useRef to get the value in input element. Just likes this.

open React

@get external value: Dom.element => string = "value"

@react.component
let make = () => {
  let (file, setFile) = useState(_ => "")
  let inputRef = useRef(Js.Nullable.null)

  <>
    <input
      type_="file"
      id="input"
      onChange={evt => setFile(_ => EventUtil.files(evt)[0])}
      ref={ReactDOM.Ref.domRef(inputRef)}
    />

    <button
      onClick={_ => inputRef.current->Js.Nullable.toOption->Belt.Option.getUnsafe->value->Js.Console.log}
    >
      {"click me"->React.string}
    </button>
  </>
}

But I don’t know how to set the value to None. Can anyone help me please.

Warning I am not ReScript expert. Literally been doing ReScript for like maybe a week.

However, I think this is what you are looking to do:

Playground

open React

type inputHtml
@set external setValue: (inputHtml, string) => unit = "value"
@get external getValue: inputHtml => option<string> = "value"
external getInput: Dom.element => inputHtml = "%identity"

@react.component
let make = () => {
  let (file, setFile) = useState(_ => "")
  let inputRef = useRef(Js.Nullable.null)

  <>
    <input
      type_="file"
      id="input"
      ref={ReactDOM.Ref.domRef(inputRef)}
    />

    <button
      onClick={_ => {
        switch (inputRef.current -> Js.Nullable.toOption) {
        	| Some(element) => element -> getInput -> setValue("")
          | None => Js.log("nothing")
        }
  	}}
    >
      {"click me"->React.string}
    </button>
  </>
}
2 Likes

They key is to cast the element into a made-up type, and then create a function that will set that value on that type.

1 Like

This is exactly what I’m looking for! Thank you.

I’m not familiar with rescript, so I didn’t know how to use @set.
Now I knew it. Thank you!

@icchi
I don’t want this to be magical. You can read about it here: Bind to JS Object | ReScript Language Manual (rescript-lang.org)

I am almost certain that using @set is just compiler sugar magic for doing this:

type inputHtml = {
  mutable value:string
}

let setValue: (inputHtml, string) => unit = (ipt, str) => ipt.value = str

As you could have done that to solve your problem.
Playground

or more directly
Playground

Thank you. I will use @set carefully.