【问题标题】:Typescript and Context API, Error: Rendered more hooks than during the previous renderTypescript 和 Context API,错误:渲染的钩子比上一次渲染时更多
【发布时间】:2021-04-06 17:02:52
【问题描述】:

我正在尝试在应用程序中同时实现 Typescript 和 Context API。在这种情况下,我正在尝试为登录创建 Context API。

这是我得到的错误: Error: Rendered more hooks than during the previous render.

我不确定我做错了什么,这是我的代码:

StateProvider.tsx:

import React, {
  Reducer,
  Dispatch,
  createContext,
  useContext,
  useReducer,
} from "react";

import  { initialState, LoginState } from "./reducer";

export type StateContextType={
  state: unknown;
  dispatch({}):void;
}

export const StateContext = createContext<StateContextType>({state: {}, dispatch: ()=>{}});

interface IProvider{
  reducer:any;
  initState:typeof initialState;
  children:any;
}

export const StateProvider:React.FC<IProvider> = ({
  reducer,
  initState,
  children,
}) => {
  const [state, dispatch] = useReducer(reducer, initState);
  const value = { state, dispatch };
  return (
    <StateContext.Provider value={value}>{children}</StateContext.Provider>
  );
};

export const useStateValue = () => useContext(StateContext);

reducer.tsx:

import React, { useState } from "react";
import axios from "./axios";
import { Button, TextField } from "@material-ui/core";
import { Link, useHistory } from "react-router-dom";
import { useStateValue } from './StateProvider'

export const initialState: LoginState = {
  user: null,
};

export interface LoginState {
  user: string | object | null;
}

type LoginAction = { type: "SET_USER"; payload: string };

function reducer(state: LoginState, action: LoginAction) {
  switch (action.type) {
    case "SET_USER":
      return {
        ...state,
        user: action.payload,
      };

    default:
      return state;
  }
}

export default function LoginUseReducer() {
  const {state, dispatch} = useStateValue();

  const [email, setEmail] = useState("");

  const [password, setPassword] = useState("");

  const history = useHistory();

  const loginHandler = (e: React.FormEvent) => {
    e.preventDefault();

    const data = {
      Email: email,
      Password: password,
    };
    axios
      .put("/auth", data)
      .then((response) => {
        console.log(response);
        dispatch({ type: "SET_USER", payload: response });
      })
      .catch((error) => {
        console.log(error.message);
      });
  };

  const handleEmailChange: React.ChangeEventHandler<HTMLInputElement> = (
    event
  ) => {
    setEmail(event.target.value);
  };

  const handlePasswordChange: React.ChangeEventHandler<HTMLInputElement> = (
    event
  ) => {
    setPassword(event.target.value);
  };

  return (
    <div>
      <TextField
        label="Email"
        variant="standard"
        helperText="Use your student email (JhonDoe@stud.uni-obuda.hu)"
        value={email}
        onChange={handleEmailChange}
        style={{ width: "80%", marginBottom: 30 }}
      ></TextField>
      <TextField
        label="Password"
        variant="standard"
        type="password"
        value={password}
        onChange={handlePasswordChange}
        style={{ width: "80%" }}
      ></TextField>
      <div className="form_buttons" style={{ marginTop: 30 }}>
        <Button
          onClick={loginHandler}
          style={{ fontSize: "large", padding: 15, width: 100 }}
        >
          Send
        </Button>
      </div>
    </div>
  );
}

登录.tsx:

import React from 'react';
import './Login.scss';
import LoginUseReducer, { initialState } from "../../reducer";

function Login() {
    return (
        <div>
            {LoginUseReducer()}
        </div>
    )
}
export default Login;

如果你们有任何想法,请告诉我。感谢您的宝贵时间!

【问题讨论】:

    标签: reactjs typescript react-hooks react-context use-reducer


    【解决方案1】:

    LoginUseReducer 用作组件而不是其他用户指出的功能时,我创建了一个按预期工作的codesandbox。我还做了一些小的修改来帮助解决此类问题。

    【讨论】:

    • 谢谢!您的解决方案对我帮助很大:D
    【解决方案2】:

    LoginUseReducer 需要像组件一样渲染,而不是像函数一样调用

    function Login() {
        return (
            <div>
                <LoginUseReducer />
            </div>
        )
    }
    export default Login;
    

    【讨论】:

    • 我得到了同样的错误:(编译器现在说 LoginUsereducer 的 const [email, setEmail] = useState(""); 在 StateProvider 的 const [state, dispatch] = useReducer(reducer, initState); 并在 reducer 的 dispatch({ type: "SET_USER", payload: response });
    • 你能展示一下StateProvider组件的使用位置和方式吗
    • 当然 index.tsx: ``` import { StateProvider } from './StateProvider';从'./reducer'导入reducer,{initialState}; ReactDOM.render( , document.getElementById("root") ); ``` 然后在reducer中你可以看到upper,仅此而已。希望对你有帮助。
    猜你喜欢
    • 2021-12-01
    • 2021-10-12
    • 2021-02-09
    • 2019-12-24
    • 2020-05-26
    • 2023-02-13
    • 2020-07-10
    • 2021-05-31
    • 2020-11-26
    相关资源
    最近更新 更多