Redux action throwing "TypeError: Cannot read property 'num_of_players' of undefined" in mapStateToProps function
Redux action throwing "TypeError: Cannot read property 'num_of_players' of undefined" in mapStateToProps function
我是 react/redux 的新手,正在尝试构建一个掷骰子游戏。我在 PregameContainer 中定义了 mapStateToProps,因为我希望用户能够 select 玩家数量和玩家名称,然后在游戏期间将其映射到子组件的道具。但是,当我尝试使用游戏按钮更改商店中的状态时,它会抛出错误:
我知道 mapStateToProps 函数将在商店数据更改时被调用。我不明白的是为什么状态第二次为空。
这是我的一些文件。了解我对这个框架非常陌生,而且我确信我没有把东西放在正确的地方。任何帮助将不胜感激。
#PregameContainer.js
import React, { Component } from 'react'
import { connect } from 'react-redux'
import PregameInput from './PregameInput'
import Game from '../Game'
class PregameContainer extends Component {
render(){
return (
<div>
{this.props.isSubmitted === false && <PregameInput submit={this.props.submit}/>}
{this.props.isSubmitted && <Game settings={this.props}/>}
</div>
)
}
}
const mapStateToProps = state => ({
num_of_players: state.num_of_players,
p1: state.p1,
p2: state.p2,
p3: state.p3,
p4: state.p4,
isSubmitted: state.isSubmitted,
})
const mapDispatchToProps = dispatch => ({
submit: game => dispatch({type: 'SUBMIT', game}),
roll: roll => dispatch({type: 'ROLL', roll}),
keep: keep => dispatch({type: 'KEEP', keep}),
end: end => dispatch({type: 'END', end}),
})
export default connect(mapStateToProps, mapDispatchToProps)(PregameContainer)
#Game.js
import React, { Component } from 'react';
import { connect } from 'react-redux'
import Score from './scoreboard/Score'
import PlayerKeep from './table/board/PlayerKeep'
import RollBoard from './table/board/RollBoard'
import ButtonsContainer from './table/board/ButtonsContainer'
class Game extends Component{
constructor(props) {
super(props);
this.state = {
}
}
player(){ let x
if (this.props.current_player === 1) x = this.props.settings.p1
else if(this.props.current_player === 2) x = this.props.settings.p2
else if(this.props.current_player === 3) x = this.props.settings.p3
else x = this.props.settings.p4
return x;
}
render()
{
return (
<div className="game_container">
<div>
<div className="board_container">
<h4 > {this.player()}'s Turn!</h4>
<h6 className="turn">TURN {this.props.current_turn} </h6>
<br></br><br></br>
<RollBoard settings={this.props}/>
<br></br>
<PlayerKeep settings={this.props}/>
<ButtonsContainer settings={this.props}/>
</div>
</div>
<Score settings={this.props.settings}/>
</div>
)
}
}
const mapStateToProps = state => ({p1_score: 0,
p2_score: 0,
p3_score: 0,
p4_score: 0,
current_player: 1,
current_turn: 1,
keep_value: 0,
rollable_dice: 6,
rolled_dice: [],
kept_dice: [],
selected_value: 0,
})
export default connect(mapStateToProps)(Game)
#manageGame.js (reducer)
export default function manageGame(state = {
p1_score: 0,
p2_score: 0,
p3_score: 0,
p4_score: 0,
current_player: 1,
current_turn: 1,
keep_value: 0,
rollable_dice: 6,
kept_dice: [],
rolled_dice: [],
selected_value: 0,
p1:"Player 1",
p2:"Player 2",
p3:"Player 3",
p4:"Player 4",
num_of_players: 2,
isSubmitted: false
}, action) {
switch (action.type) {
case 'SUBMIT':
const settings = { game: action.game };
return {
...state,
p1: settings.game.p1,
p2: settings.game.p2,
p3: settings.game.p3,
p4: settings.game.p4,
num_of_players: settings.game.num_of_players,
isSubmitted: true
}
case 'ROLL':
return {
...state,
rolled_dice: Array.from({length: state.rollable_dice}, () => Math.floor(Math.random() * 6))
}, console.log(state);
case 'KEEP':
const keep = { game: action.keep };
return{
};
case 'END':
const end = { game: action.end };
return{
...state,
};
default:
return state;
}
}
这就是引发错误的原因(“滚动”按钮)-
import React, { Component } from 'react';
import { connect } from 'react-redux'
class GameButtons extends Component {
constructor(props) {
super(props);
};
render(){
return (
<div>
{console.log(this.props)}
<button onClick={this.props.settings.settings.roll} className="game_buttons" >Roll Dice</button>
<button onClick={this.props.keep} className="game_buttons">Keep Selected</button>
<button onClick={this.props.end} className="game_buttons">End Turn</button>
</div>
)
}
}
export default connect()(GameButtons)
你的减速器有一个错误。
case 'ROLL':
return {
...state,
rolled_dice: Array.from({length: state.rollable_dice}, () => Math.floor(Math.random() * 6))
}, console.log(state);
return 表达式的计算结果为 undefined
。问题是您无意中使用了 javascript 鲜为人知的 comma operator。 return 值将是逗号后的右侧值,即 console.log()
调用,始终为 undefined
。这就是您收到此错误的原因,因为传递给 mapStateToProps
的 redux 状态现在是 undefined
.
去掉逗号语句。
如果要写入控制台,请在 return 语句之前执行。
case 'ROLL':
console.log(state);
return {
...state,
rolled_dice: Array.from({length: state.rollable_dice}, () => Math.floor(Math.random() * 6))
};
但最好让您的 reducer 函数保持纯净,并避免在您的 reducer 内部产生任何副作用(写入控制台是一种副作用)。您可以考虑使用 redux-logger 中间件代替 https://www.npmjs.com/package/redux-logger
我是 react/redux 的新手,正在尝试构建一个掷骰子游戏。我在 PregameContainer 中定义了 mapStateToProps,因为我希望用户能够 select 玩家数量和玩家名称,然后在游戏期间将其映射到子组件的道具。但是,当我尝试使用游戏按钮更改商店中的状态时,它会抛出错误:
我知道 mapStateToProps 函数将在商店数据更改时被调用。我不明白的是为什么状态第二次为空。
这是我的一些文件。了解我对这个框架非常陌生,而且我确信我没有把东西放在正确的地方。任何帮助将不胜感激。
#PregameContainer.js
import React, { Component } from 'react'
import { connect } from 'react-redux'
import PregameInput from './PregameInput'
import Game from '../Game'
class PregameContainer extends Component {
render(){
return (
<div>
{this.props.isSubmitted === false && <PregameInput submit={this.props.submit}/>}
{this.props.isSubmitted && <Game settings={this.props}/>}
</div>
)
}
}
const mapStateToProps = state => ({
num_of_players: state.num_of_players,
p1: state.p1,
p2: state.p2,
p3: state.p3,
p4: state.p4,
isSubmitted: state.isSubmitted,
})
const mapDispatchToProps = dispatch => ({
submit: game => dispatch({type: 'SUBMIT', game}),
roll: roll => dispatch({type: 'ROLL', roll}),
keep: keep => dispatch({type: 'KEEP', keep}),
end: end => dispatch({type: 'END', end}),
})
export default connect(mapStateToProps, mapDispatchToProps)(PregameContainer)
#Game.js
import React, { Component } from 'react';
import { connect } from 'react-redux'
import Score from './scoreboard/Score'
import PlayerKeep from './table/board/PlayerKeep'
import RollBoard from './table/board/RollBoard'
import ButtonsContainer from './table/board/ButtonsContainer'
class Game extends Component{
constructor(props) {
super(props);
this.state = {
}
}
player(){ let x
if (this.props.current_player === 1) x = this.props.settings.p1
else if(this.props.current_player === 2) x = this.props.settings.p2
else if(this.props.current_player === 3) x = this.props.settings.p3
else x = this.props.settings.p4
return x;
}
render()
{
return (
<div className="game_container">
<div>
<div className="board_container">
<h4 > {this.player()}'s Turn!</h4>
<h6 className="turn">TURN {this.props.current_turn} </h6>
<br></br><br></br>
<RollBoard settings={this.props}/>
<br></br>
<PlayerKeep settings={this.props}/>
<ButtonsContainer settings={this.props}/>
</div>
</div>
<Score settings={this.props.settings}/>
</div>
)
}
}
const mapStateToProps = state => ({p1_score: 0,
p2_score: 0,
p3_score: 0,
p4_score: 0,
current_player: 1,
current_turn: 1,
keep_value: 0,
rollable_dice: 6,
rolled_dice: [],
kept_dice: [],
selected_value: 0,
})
export default connect(mapStateToProps)(Game)
#manageGame.js (reducer)
export default function manageGame(state = {
p1_score: 0,
p2_score: 0,
p3_score: 0,
p4_score: 0,
current_player: 1,
current_turn: 1,
keep_value: 0,
rollable_dice: 6,
kept_dice: [],
rolled_dice: [],
selected_value: 0,
p1:"Player 1",
p2:"Player 2",
p3:"Player 3",
p4:"Player 4",
num_of_players: 2,
isSubmitted: false
}, action) {
switch (action.type) {
case 'SUBMIT':
const settings = { game: action.game };
return {
...state,
p1: settings.game.p1,
p2: settings.game.p2,
p3: settings.game.p3,
p4: settings.game.p4,
num_of_players: settings.game.num_of_players,
isSubmitted: true
}
case 'ROLL':
return {
...state,
rolled_dice: Array.from({length: state.rollable_dice}, () => Math.floor(Math.random() * 6))
}, console.log(state);
case 'KEEP':
const keep = { game: action.keep };
return{
};
case 'END':
const end = { game: action.end };
return{
...state,
};
default:
return state;
}
}
这就是引发错误的原因(“滚动”按钮)-
import React, { Component } from 'react';
import { connect } from 'react-redux'
class GameButtons extends Component {
constructor(props) {
super(props);
};
render(){
return (
<div>
{console.log(this.props)}
<button onClick={this.props.settings.settings.roll} className="game_buttons" >Roll Dice</button>
<button onClick={this.props.keep} className="game_buttons">Keep Selected</button>
<button onClick={this.props.end} className="game_buttons">End Turn</button>
</div>
)
}
}
export default connect()(GameButtons)
你的减速器有一个错误。
case 'ROLL':
return {
...state,
rolled_dice: Array.from({length: state.rollable_dice}, () => Math.floor(Math.random() * 6))
}, console.log(state);
return 表达式的计算结果为 undefined
。问题是您无意中使用了 javascript 鲜为人知的 comma operator。 return 值将是逗号后的右侧值,即 console.log()
调用,始终为 undefined
。这就是您收到此错误的原因,因为传递给 mapStateToProps
的 redux 状态现在是 undefined
.
去掉逗号语句。 如果要写入控制台,请在 return 语句之前执行。
case 'ROLL':
console.log(state);
return {
...state,
rolled_dice: Array.from({length: state.rollable_dice}, () => Math.floor(Math.random() * 6))
};
但最好让您的 reducer 函数保持纯净,并避免在您的 reducer 内部产生任何副作用(写入控制台是一种副作用)。您可以考虑使用 redux-logger 中间件代替 https://www.npmjs.com/package/redux-logger