Reactjs useSelector 重新渲染太多。 React 限制渲染次数以防止无限循环

Reactjs useSelector Too many re-renders. React limits the number of renders to prevent an infinite loop

我想在我的 react typescript 应用程序中使用 redux

我已经能够创建 redux 存储并且

也分派到 redux

我想获取发送到商店的价值

使用 useSelector 但出现此错误

Too many re-renders. React limits the number of renders to prevent an infinite loop.

我的代码

UserReducer

export const userReducer = (state=null, action) => {
   switch(action.type){
     case "LOGIN":
       return action.payload;
     case "LOGOUT":
       return action.payload;
    case default:
       return state;
    }
}

Login.tsx

import React, { useState } from "react";
import {useDispatch, useSelector} from 'react-redux'
const Login = () => {
  const reduxState= useSelector((state) => state);
  dispatch({
   type: "LOGIN",
   payload: "token"
 });
  return (
    <div className="__login">
       {JSON.stringify(reduxState)}
    </div>
  )
};

export default Login;

App.tsx

import React from 'react';
function App() {
  return (
    <div className="App">
       <Routes>
         <Route  path="/login" element={ <Login />} />
      </Routes>
       
    </div>
  );
}

export default App;

index.tsx

从“react”导入 React;

import { createStore } from "redux";
import { Provider } from "react-redux";
import { composeWithDevTools } from "redux-devtools-extension";
import rootReducer from "./reducers";
// create store
const store = createStore(rootReducer, composeWithDevTools());
ReactDOM.render(
  <Provider store={store}>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </Provider>,
  document.getElementById("root")
);
reportWebVitals();

logout.tsx

注销是我单击以通过删除令牌并将状态更改为空来更改应用程序状态的地方

import React, { useState } from "react";
import {useDispatch, useSelector} from 'react-redux'
const logout= () => {
  const reduxState= useSelector((state) => state);
 const logoutApp = () => {
      dispatch({
         type: "LOGOUT",
         payload: null
     });
 }
  return (
    <div className="__login">
        <span onClick={logoutApp}>logout</span>
    </div>
  )
};

export default logout;

您的调度就在登录组件内。 React 功能组件在其每次渲染时运行组件中的所有内容。

import React, { useState } from "react";
import {useDispatch, useSelector} from 'react-redux'
const Login = () => {
  const reduxState= useSelector((state) => state);
  
  dispatch({ //This dispatch will call on it's every render, so after success login it will call dispatch again, and then again ... it leads to an infinite loop 
   type: "LOGIN",
   payload: "token"
   });
  return (
    <div className="__login">
       {JSON.stringify(reduxState)}
    </div>
  )
};

export default Login;

最好的方法是将其移动到按钮点击。或 useEffect.

方法一,点击按钮登录

import React, { useState } from "react";
import {useDispatch, useSelector} from 'react-redux'
const Login = () => {
    const reduxState= useSelector((state) => state);

    const login = () => {
      dispatch({ 
       type: "LOGIN",
       payload: "token"
      });
    }
    return (
      <div className="__login">
         {JSON.stringify(reduxState)}
          <button onClick={login} >login</button>
      </div>
    )
  };

  export default Login;

方法二.在useEffect中调用

import React, { useState,useEffect } from "react";
import {useDispatch, useSelector} from 'react-redux'
const Login = () => {
    const reduxState= useSelector((state) => state);

    useEffect(() => {
      dispatch({ 
       type: "LOGIN",
       payload: "token"
      });
    },[]) //this useEffect will only call on its first render

    return (
      <div className="__login">
         {JSON.stringify(reduxState)}
      </div>
    )
  };

  export default Login;