简体   繁体   中英

React setState not setting property to File value

I'm trying to create a custom useForm hook which will update an object and handle multiple input types. When I upload an image, I grab the first image and save it to value BUT when I setState with setInputs , the image value in the inputs object is null even though the value is the File object (as I've console logged it before).

I'm not sure if this is a typescript specific error. I tried setting profileImage to be any without any impact.

EDIT: The image is being uploaded correctly, but not displaying when using JSON.stringify as mentioned in the comments... so no actual error.

// Hook usage
const { inputs, handleInput } = useForm<{
  name: string
  description: string
  profileImage: File | null
}>({
  name: "",
  description: "",
  profileImage: null,
})
// Form Input
<input
  onChange={handleInput}
  type="file"
  accept="image/*"
  id="profileImage"
  name="profileImage"
/>
// useForm hook
export type FormEvent = React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>

export default function useForm<T extends { [key: string]: any }>(initial: T = {} as T) {
  const [inputs, setInputs] = useState<T>(initial)

  const handleInput = (e: FormEvent) => {
    let { value, name, type }: { value: any; name: string; type: string } = e.target
    if (type === "number") {
      value = parseInt(value)
    } else if (type === "file") {
      value = (e.target as HTMLInputElement).files![0]
    }
    setInputs({ ...inputs, [name]: value })
  }

  return { inputs, setInputs, handleInput }
}

I reproduced a simplified version of your example, just handling the file case. The upload onChange action is handled by the hook, file object is returned and name gets displayed on the HTML.

https://codesandbox.io/s/condescending-mcclintock-qs3c1?file=/src/App.js

function useForm(init) {
  const [file, setFile] = React.useState(init);
  const handleFileInput = (e) => {
    setFile(e.target.files[0]);
  };
  return {file, handleFileInput};
}


export default function App() {
  const {file, handleFileInput } = useForm(null);

  console.log('file', file);
  return (
    <div className="App">
      <h3>File Upload Test</h3>
      <input type="file" onChange={handleFileInput} />
      <div> File Info: {file && file.name} </div>
    </div>
  );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM