问题描述
我正在尝试使用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())}