在简单的React-Redux应用程序上出现``错误:重新渲染过多''

问题描述

我正在尝试使用React-Redux构建一个简单的应用,该应用从状态获取报价并将其呈现到页面上。现在,我将应用程序的主要功能包含在名为QuoteBox功能组件中,并将其呈现在名为App的另一个功能组件中,然后将其包装在React-Redux Provider中,最后呈现到页面中:

./src/features/QuoteBox/QuoteBox.jsx

import React from 'react'
import { useSelector,usedispatch } from 'react-redux'
import {
  initialize,getNewQuote,selectQuote
} from './quoteBoxSlice'
import styles from './QuoteBox.module.css'

export function QuoteBox() {
  const currentQuote = useSelector(selectQuote)
  const dispatch = usedispatch()

  return (
    <div
      className={styles['quote-Box']}
      onLoad={dispatch(initialize())}
      >
      <p className={styles['text']}>{currentQuote['quote']}</p>
      <p className={styles['author']}>{currentQuote['author']}</p>
      <button
        className={styles['new-quote']}
        onClick={dispatch(getNewQuote())}
        >New Quote!</button>
    </div>
  );
}

./src/features/QuoteBox/quoteBoxSlice.js

import { createSlice } from '@reduxjs/toolkit'

function randomIndex(n) {
  return Math.floor(Math.random() * n);
}

export const slice = createSlice({
  name: 'quoteBox',initialState: {
    allQuotes: [],currentQuote: {}
  },reducers: {
    initialize: state => {
      state['allQuotes'] = [
        { author: 'Author One',quote: 'Quote One' },{ author: 'Author Two',quote: 'Quote Two' },{ author: 'Author Three',quote: 'Quote Three' },{ author: 'Author Four',quote: 'Quote Four' },{ author: 'Author Five',quote: 'Quote Five' }
      ]
      state['currentQuote'] = state['allQuotes'][
        randomIndex(state['allQuotes'].length)
      ]
    },getNewQuote: state => {
      state['currentQuote'] = state['allQuotes'][
        randomIndex(state['allQuotes'].length)
      ]
    }
  }
})

export const { initialize,getNewQuote } = slice.actions

export function selectQuote(state) {
  return state['quoteBox']['currentQuote'];
}

export default slice.reducer

./src/app/store.js

import { configureStore } from '@reduxjs/toolkit'
import quoteBoxReducer from '../features/QuoteBox/quoteBoxSlice'

export default configureStore({
  reducer: {
    quoteBox: quoteBoxReducer
  }
})

./src/App.jsx

import React from 'react'
import { QuoteBox } from './features/QuoteBox/QuoteBox'

function App() {  
  return (
    <div>
      <QuoteBox />
    </div>
  );
}

export default App

./src/index.js

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import store from './app/store'
import { Provider } from 'react-redux'

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,document.getElementById('root')
)

错误页面给了我以下反馈:

**18 stack frames were expanded.**
**renderWithHooks**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:14815
**updateFunctionComponent**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:17034
**beginWork**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:18610
**callCallback**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:188
**invokeGuardedCallbackDev**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:237
**invokeGuardedCallback**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:292
**beginWork$1**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:23203
**performunitOfWork**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:22157
**workLoopSync**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:22130
**performSyncWorkOnRoot**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:21756
**flushSyncCallbackQueueImpl/<**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:11089
**unstable_runWithPriority**
C:/Users/jpaul/Desktop/quote-Box/node_modules/scheduler/cjs/scheduler.development.js:653
**runWithPriority$1**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:11039
**flushSyncCallbackQueueImpl**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:11084
**flushSyncCallbackQueue**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:11072
**unbatchedUpdates**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:21909
**legacyRenderSubtreeIntoContainer**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:24757
**render**
C:/Users/jpaul/Desktop/quote-Box/node_modules/react-dom/cjs/react-dom.development.js:24840

什么在这里引起无限循环?

解决方法

QuoteBox中,您是在渲染时调用调度,而不是单击时。这将更改报价,导致QuoteBox的重新提交,从而导致无限次的发送。更改此:

onClick={dispatch(getNewQuote())}

对此:

onClick={() => dispatch(getNewQuote())}