如何正确地将事件处理程序作为道具传递给Typescript react组件?

时间:2020-06-12 22:57:10

标签: reactjs typescript

我正在尝试传递此handleSubmit事件处理程序,但不知道我在做什么错。如果我在子组件上使用匿名函数,则该函数运行良好。编译器不会抛出任何错误,当您突出显示VS Code上的“ onSubmit”道具时,我就使用了键入。

这是父组件。

const App: React.FC = () => {
  const [auth, setAuth] = useState<boolean>(false);

  const authToken = () => Math.random().toString(36).substr(2);

  const handleSubmit = ((e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    localStorage.setItem("token", JSON.stringify(authToken()));
    setAuth(true);
    console.log('submit works');
  });


  return (
    <div>
      <Navbar />
      <Switch>
        <Route path="/" exact={true} handleSubmit={handleSubmit} auth={auth} component={Login} />
        <Route path="/userlist" component={UserList} />
        <Route path="/editscreen" component={EditScreen} />
      </Switch>
    </div>
  );
};

export default App;


和子组件

interface Props {
  handleSubmit: ((e: React.FormEvent<HTMLFormElement>) => void);
  auth: boolean;
}

const Login: React.FC<Props> = ({ handleSubmit, auth }) => {
  const [email, setEmail] = useState<string>("");
  const [password, setPassword] = useState<string>("");

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <label>E-mail</label>
        <input
          onChange={(e) => setEmail(e.target.value)}
          type="email"
          name="email"
          value={email}
          required
        ></input>
        <label>Password</label>
        <input
          onChange={(e) => setPassword(e.target.value)}
          type="password"
          name="password"
          value={password}
          required
        ></input>
        <button type="submit">SUBMIT!</button>
      </form>
    </div>
  );
};

export default Login;

2 个答案:

答案 0 :(得分:0)

您需要将处理程序作为“登录”组件的道具传递,而不是作为“路由”组件的道具传递。

尝试一下:

<Route path="/" exact={true} render={(props) => <Login {...props} handleSubmit={handleSubmit} auth={auth} />} />

或:

<Route path="/" exact={true} component={() => <Login handleSubmit={handleSubmit} auth={auth} />} />

但是由于性能原因,不建议使用最后一个。 https://reacttraining.com/react-router/web/api/Route/component

答案 1 :(得分:0)

<Route>上传递任意道具不会像这样过滤掉渲染的组件。您可能希望将带有所有所需道具的子组件作为子组件传入。

代替:

<Route
  path="/"
  exact={true}
  handleSubmit={handleSubmit}
  auth={auth}
  component={Login}
/>

尝试:

<Route path="/" exact={true}>
  <Login handleSubmit={handleSubmit} auth={auth} />
</Route>

通过这种方式,很明显,这条路线是什么道具,以及该路线所呈现的组件的什么道具。