简体   繁体   中英

App breaking when trying to use usetState in React/TypeScript app

Expected

Being able to use useState to set an email and password var inside of a functional React component.

Then using onChange on the inputs to change those variables, then sent the results of those variables up to the parent class via the signIn function.

Results

There is a typescript error highlighted over the onChange , and the app breaks.

Code

import React, {useState} from 'react'

import {
  AuthArea,
  AuthInputs,
  CreateNewAccount,
  FunctionButton
} from '../../styles'

interface IProps {
  signIn(email: string, password: string): void
}

export default ({ signIn }: IProps) => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  return (
    <AuthArea>
      <h1>Sign In</h1>
      <AuthInputs>
        <input
          type="text"
          placeholder="Email"
          value={email}
          onChange={setEmail}
        />
        <input
          type="password"
          placeholder="Password"
          value={password}
          onChange={setPassword}
        />
        <FunctionButton onClick={() => signIn(email, password)}>
          Sign In
        </FunctionButton>
        <a href="#">Forgot Password?</a>
      </AuthInputs>
      <CreateNewAccount>
        Create New Account
      </CreateNewAccount>
    </AuthArea>
  )
}

The error

(JSX attribute) React.InputHTMLAttributes.onChange?: ((event: React.ChangeEvent) => void) | undefined Type 'Dispatch>' is not assignable to type '(event: ChangeEvent) => void'. Types of parameters 'value' and 'event' are incompatible. Type 'ChangeEvent' is not assignable to type 'SetStateAction'. Type 'ChangeEvent' is not assignable to type '(prevState: string) => string'. Type 'ChangeEvent' provides no match for the signature '(prevState: string): string'.ts(2322) index.d.ts(1976, 9): The expected type comes from property 'onChange' which is declared here on type 'DetailedHTMLProps, HTMLInputElement>'

在此处输入图片说明

This is how you setState in onChange:

<input
     type="text"
     placeholder="Email"
     value={email}
     onChange={(e) => setEmail(e.target.value)}
/>
<input
     type="password"
     placeholder="Password"
     value={password}
     onChange={(e) => setPassword(e.target.value)}
/>

Another version with extracted out function and using currying method for re-usability is as below:

export default ({ signIn }) => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleChange = setterFunc => e => {
    const value = e.target.value;
    setterFunc(value);
  }

  return (
    <>
      <input
        type="text"
        placeholder="Email"
        value={email}
        onChange={handleChange(setEmail)}
      />
      <input
        type="password"
        placeholder="Password"
        value={password}
        onChange={handleChange(setPassword)}
      />
    </>
  )
}

Here's live version: https://stackblitz.com/edit/react-rf4bhw

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