【问题标题】:Reactjs useSelector Too many re-renders. React limits the number of renders to prevent an infinite loopReactjs useSelector 重新渲染太多。 React 限制渲染次数以防止无限循环
【发布时间】:2022-01-19 00:46:55
【问题描述】:

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

我已经能够创建 redux 商店和

也派发到 redux

我想将价值分派到商店

使用 useSelector 但我收到此错误

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

我的代码

用户减速器

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

登录.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

从“反应”导入反应;

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();

注销.tsx

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

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;

【问题讨论】:

  • 请显示整个代码。尤其是使用组件Login的地方。考虑到状态在每次调度时都是新的。实际上,您应该使用 useSelector 选择所需的状态切片。
  • @AndrejKirejeŭ 我已经更新了我的代码
  • 有没有修改状态的地方?
  • 显示您的调度
  • @sojin 在登录页面发送

标签: javascript reactjs redux react-redux


【解决方案1】:

您的调度只是在登录组件内。 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;

方法2.在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;

【讨论】:

    猜你喜欢
    • 2020-08-07
    • 2020-08-06
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    • 2020-09-22
    • 2021-07-01
    相关资源
    最近更新 更多