React-Redux添加对象到列表时报Maximum call stack size exceeded如何解决
问题修复方案
核心问题点
- 未包裹的顶层dispatch触发无限重渲染:你注释掉的
dispatch(addPlayerToList('Test'))如果直接写在组件函数体内部,没有包裹在依赖为空数组的useEffect中,会在每次组件渲染时执行,触发redux state更新后又导致组件重渲染,形成无限循环。
- 未包裹的顶层dispatch触发无限重渲染:你注释掉的
- action调用名称错误:
addPlayer函数内调用的dispatch方法参数错误,你导入的添加玩家action是addPlayerToList,但你错误传入了当前函数自身addPlayer,会引发逻辑异常。
- action调用名称错误:
- reducer初始值错误:
playerListReducer的初始值设为null,第一次执行添加玩家操作时,[...state, action.data]对null做展开会直接抛出JS错误,初始值应该改为空数组[]。
- reducer初始值错误:
- 基础语法错误:
renderPlayerList中map渲染玩家名时没有用{}包裹变量、没有给列表项加唯一key属性,input作为受控组件缺少value绑定,同时你没有在JSX中调用renderPlayerList方法展示列表。
- 基础语法错误:
修复后的代码
App.js
import React, { useEffect } from 'react' import {useDispatch, useSelector} from 'react-redux'; import './App.css'; import {setPlayerName, addPlayerToList} from './redux/reducers/playerReducer'; function App() { const dispatch = useDispatch() const playerName = useSelector(state => state.playerName); const playerList = useSelector(state => state.playerList); // 若需要初始化加载测试玩家,用下方useEffect,空依赖数组只会在组件挂载时执行一次 // useEffect(() => { // dispatch(addPlayerToList('Test')) // }, [dispatch]) const addPlayer = (player) => { // 修正action调用名称 dispatch(addPlayerToList(player)) dispatch(setPlayerName('')) } const renderPlayerList = () => { if (playerList.length < 1) { return ( <div> No Players </div> ) } else { return ( playerList.map(p => <p key={p.name}>{p.name}</p> ) ) } } return ( <div className="App"> <input type='text' name='playerName' value={playerName} onChange={({ target }) => dispatch(setPlayerName(target.value))} required /> Name<br/> <button type='button' onClick={() => addPlayer(playerName)} > Add Player</button> <br /> <br /> {/* 调用方法渲染玩家列表 */} {renderPlayerList()} </div> ); } export default App;
playerReducer.js
export const playerNameReducer = (state = '', action) => { switch (action.type) { case 'SET_PLAYER_NAME': return action.data; default: return state; } }; export const playerListReducer = (state = [], action) => { switch (action.type) { case 'ADD_PLAYER': return [...state, action.data]; default: return state; } };
内容的提问来源于stack exchange,提问作者codenoob9000
相关产品推荐
相关产品推荐

