TypeError: Cannot read property 'type' of undefined Error before any Components even render
TypeError: Cannot read property 'type' of undefined Error before any Components even render
我的 Redux 应用程序甚至不会呈现第一个组件 (App.js),因为它一直出错。在某些时候,它会在没有任何操作的情况下触发 reducer(如下所示),因此当编译器到达行 switch(action.type)
时,它一直认为操作为空,因此它找不到 type
属性任何地方。事实上,我有一个 console.log 作为函数的第一行,当 App.js 被渲染时立即调用它甚至不会触发,这意味着代码甚至在渲染单个组件之前就中断了.请记住,我在 index.js
中设置了 <Provider />
标签,它呈现 App.js
------------------------减速器-------------------- ------
const rootReducer = combineReducers({
battle: manageBattle,
user: manageUser // Ignore this right now, it's not in any components that are getting rendered
})
export default rootReducer
function manageBattle(
action,
state={
figures:{ // The following figures are temporary as the stats will ne changed during the battle.
user: { // We save the original user stats under the manageUser reducer
is_user: true, // Might be needed. Might not, we'll find out
name: "", // The name of the user figure
class_type: null,
id: null, // Generated in Rails
hp: 0, // Health
type: null, // Type, one of... TECH, WEAPONRY, SUPERNATURAL, ATHLETIC, NETHER, STEALTH. Each has a different effectiveness on the other
level: 0, // Keeps track of how many fights they have won
status: "none", // Certins moves (generated by Rails) have status effects. This variable holds what effects (if any) are present on the user
spd: 0, // Speed
atk: 0, // Attack
def: 0, // Defense... you get it right?
sAtk: 0, //
sDef: 0, //
tEffected: 0, // How many turns the user has been effected by a status effect. 0 if unaffected
image: "N/A", // Generated by Rails and used to determine with jpeg to load
moves: [null] // Sets an empty array for the moves and setting that up is gonna suck so I'm avoiding it
},
opp: {
is_user: false,
name: "",
class_type: null,
id: null, // See Above
hp: 0,
type: null,
level: 0,
status: "none",
spd: 0,
atk: 0,
def: 0,
sAtk: 0,
sDef: 0,
tEffected: 0,
image: "N/A",
moves: [null]
}
},
battle_details: {
turns: 0, // This will keep track of the turns elapsed
whoseTurn_id: null, // This will be set to 'user', 'opp', or 'none'.
this_move_target_id: null,
prompt: "Welcome"
}
}
){
if (!action){
console.log("Action is nil")
}
switch (action.type) {
case 'NEW_BATTLE':
// FETCH NEW BATTLE JSON
case 'CHANGE_USER_HP':
// action = {type: "CHANGE_OPP_HP", amount: {Number generated in Event Listener inside of Moves}, effect: {String generated in Event Listener} }
let effect = action.effect
let newUserState = applyingStatusEffectandDamage(state, action.amount, effect)
return {newUserState}
case 'CHANGE_OPP_HP':
// action = {type: "CHANGE_OPP_HP", amount: {Number generated in Event Listener inside of Moves}, effect: {String generated in Event Listener} }
effect = action.effect
let newOppState = applyingStatusEffectandDamage(state, action.amount, effect)
return {newOppState}
case 'COMPLETE_BATTLE':
// CHANGE PROMPT, RESET USER HP, LEVEL UP
default:
return state;
}
};
--------------------App.js--------------------
import { connect } from 'react-redux';
import './App.css';
import BattleCard from './components/containers/BattleCard';
import React, { Component } from 'react';
import CreationContainer from './components/dispatchers/CreationContainer';
class App extends Component {
intro_or_resume = (props) => {
console.log(props)
if (props.user.created === true){
return(
<div className="Battle Container">
<BattleCard />
</div>
)
}
else{
return(
<div className="Create Form">
<CreationContainer />
</div>
)
}
}
testPlease = () => {
console.log("hello!")
}
render() {
return (
<div className="Main-Window">
{this.testPlease()}
{this.intro_or_resume(this.props)}
</div>
)
}
}
const mapStateToProps = (state) => {
return { user: state.user }
}
export default connect(mapStateToProps)(App);
是 this.testPlease()
函数没有被命中,我可以在它被调用时在 reducers 中告诉它 action = nil 因为 if (!action){console.log("Action is nil")}
每次我尝试启动应用程序时都会被命中. npm start
也向我发出了几分钟的警告,但我认为不会影响到这一点;除了浏览器之外,任何地方都没有产生实际错误
您的 reducer 函数需要先排序 state
,然后排序 action
。
const rootReducer = combineReducers({
battle: manageBattle,
user: manageUser // Ignore this right now, it's not in any components that are getting rendered
})
export default rootReducer
function manageBattle(
state={
figures:{ // The following figures are temporary as the stats will ne changed during the battle.
user: { // We save the original user stats under the manageUser reducer
is_user: true, // Might be needed. Might not, we'll find out
name: "", // The name of the user figure
class_type: null,
id: null, // Generated in Rails
hp: 0, // Health
type: null, // Type, one of... TECH, WEAPONRY, SUPERNATURAL, ATHLETIC, NETHER, STEALTH. Each has a different effectiveness on the other
level: 0, // Keeps track of how many fights they have won
status: "none", // Certins moves (generated by Rails) have status effects. This variable holds what effects (if any) are present on the user
spd: 0, // Speed
atk: 0, // Attack
def: 0, // Defense... you get it right?
sAtk: 0, //
sDef: 0, //
tEffected: 0, // How many turns the user has been effected by a status effect. 0 if unaffected
image: "N/A", // Generated by Rails and used to determine with jpeg to load
moves: [null] // Sets an empty array for the moves and setting that up is gonna suck so I'm avoiding it
},
opp: {
is_user: false,
name: "",
class_type: null,
id: null, // See Above
hp: 0,
type: null,
level: 0,
status: "none",
spd: 0,
atk: 0,
def: 0,
sAtk: 0,
sDef: 0,
tEffected: 0,
image: "N/A",
moves: [null]
}
},
battle_details: {
turns: 0, // This will keep track of the turns elapsed
whoseTurn_id: null, // This will be set to 'user', 'opp', or 'none'.
this_move_target_id: null,
prompt: "Welcome"
}
}, action
){
if (!action){
console.log("Action is nil")
}
switch (action.type) {
case 'NEW_BATTLE':
// FETCH NEW BATTLE JSON
case 'CHANGE_USER_HP':
// action = {type: "CHANGE_OPP_HP", amount: {Number generated in Event Listener inside of Moves}, effect: {String generated in Event Listener} }
let effect = action.effect
let newUserState = applyingStatusEffectandDamage(state, action.amount, effect)
return {newUserState}
case 'CHANGE_OPP_HP':
// action = {type: "CHANGE_OPP_HP", amount: {Number generated in Event Listener inside of Moves}, effect: {String generated in Event Listener} }
effect = action.effect
let newOppState = applyingStatusEffectandDamage(state, action.amount, effect)
return {newOppState}
case 'COMPLETE_BATTLE':
// CHANGE PROMPT, RESET USER HP, LEVEL UP
default:
return state;
}
};
希望这对你有用。
我的 Redux 应用程序甚至不会呈现第一个组件 (App.js),因为它一直出错。在某些时候,它会在没有任何操作的情况下触发 reducer(如下所示),因此当编译器到达行 switch(action.type)
时,它一直认为操作为空,因此它找不到 type
属性任何地方。事实上,我有一个 console.log 作为函数的第一行,当 App.js 被渲染时立即调用它甚至不会触发,这意味着代码甚至在渲染单个组件之前就中断了.请记住,我在 index.js
中设置了 <Provider />
标签,它呈现 App.js
------------------------减速器-------------------- ------
const rootReducer = combineReducers({
battle: manageBattle,
user: manageUser // Ignore this right now, it's not in any components that are getting rendered
})
export default rootReducer
function manageBattle(
action,
state={
figures:{ // The following figures are temporary as the stats will ne changed during the battle.
user: { // We save the original user stats under the manageUser reducer
is_user: true, // Might be needed. Might not, we'll find out
name: "", // The name of the user figure
class_type: null,
id: null, // Generated in Rails
hp: 0, // Health
type: null, // Type, one of... TECH, WEAPONRY, SUPERNATURAL, ATHLETIC, NETHER, STEALTH. Each has a different effectiveness on the other
level: 0, // Keeps track of how many fights they have won
status: "none", // Certins moves (generated by Rails) have status effects. This variable holds what effects (if any) are present on the user
spd: 0, // Speed
atk: 0, // Attack
def: 0, // Defense... you get it right?
sAtk: 0, //
sDef: 0, //
tEffected: 0, // How many turns the user has been effected by a status effect. 0 if unaffected
image: "N/A", // Generated by Rails and used to determine with jpeg to load
moves: [null] // Sets an empty array for the moves and setting that up is gonna suck so I'm avoiding it
},
opp: {
is_user: false,
name: "",
class_type: null,
id: null, // See Above
hp: 0,
type: null,
level: 0,
status: "none",
spd: 0,
atk: 0,
def: 0,
sAtk: 0,
sDef: 0,
tEffected: 0,
image: "N/A",
moves: [null]
}
},
battle_details: {
turns: 0, // This will keep track of the turns elapsed
whoseTurn_id: null, // This will be set to 'user', 'opp', or 'none'.
this_move_target_id: null,
prompt: "Welcome"
}
}
){
if (!action){
console.log("Action is nil")
}
switch (action.type) {
case 'NEW_BATTLE':
// FETCH NEW BATTLE JSON
case 'CHANGE_USER_HP':
// action = {type: "CHANGE_OPP_HP", amount: {Number generated in Event Listener inside of Moves}, effect: {String generated in Event Listener} }
let effect = action.effect
let newUserState = applyingStatusEffectandDamage(state, action.amount, effect)
return {newUserState}
case 'CHANGE_OPP_HP':
// action = {type: "CHANGE_OPP_HP", amount: {Number generated in Event Listener inside of Moves}, effect: {String generated in Event Listener} }
effect = action.effect
let newOppState = applyingStatusEffectandDamage(state, action.amount, effect)
return {newOppState}
case 'COMPLETE_BATTLE':
// CHANGE PROMPT, RESET USER HP, LEVEL UP
default:
return state;
}
};
--------------------App.js--------------------
import { connect } from 'react-redux';
import './App.css';
import BattleCard from './components/containers/BattleCard';
import React, { Component } from 'react';
import CreationContainer from './components/dispatchers/CreationContainer';
class App extends Component {
intro_or_resume = (props) => {
console.log(props)
if (props.user.created === true){
return(
<div className="Battle Container">
<BattleCard />
</div>
)
}
else{
return(
<div className="Create Form">
<CreationContainer />
</div>
)
}
}
testPlease = () => {
console.log("hello!")
}
render() {
return (
<div className="Main-Window">
{this.testPlease()}
{this.intro_or_resume(this.props)}
</div>
)
}
}
const mapStateToProps = (state) => {
return { user: state.user }
}
export default connect(mapStateToProps)(App);
是 this.testPlease()
函数没有被命中,我可以在它被调用时在 reducers 中告诉它 action = nil 因为 if (!action){console.log("Action is nil")}
每次我尝试启动应用程序时都会被命中. npm start
也向我发出了几分钟的警告,但我认为不会影响到这一点;除了浏览器之外,任何地方都没有产生实际错误
您的 reducer 函数需要先排序 state
,然后排序 action
。
const rootReducer = combineReducers({
battle: manageBattle,
user: manageUser // Ignore this right now, it's not in any components that are getting rendered
})
export default rootReducer
function manageBattle(
state={
figures:{ // The following figures are temporary as the stats will ne changed during the battle.
user: { // We save the original user stats under the manageUser reducer
is_user: true, // Might be needed. Might not, we'll find out
name: "", // The name of the user figure
class_type: null,
id: null, // Generated in Rails
hp: 0, // Health
type: null, // Type, one of... TECH, WEAPONRY, SUPERNATURAL, ATHLETIC, NETHER, STEALTH. Each has a different effectiveness on the other
level: 0, // Keeps track of how many fights they have won
status: "none", // Certins moves (generated by Rails) have status effects. This variable holds what effects (if any) are present on the user
spd: 0, // Speed
atk: 0, // Attack
def: 0, // Defense... you get it right?
sAtk: 0, //
sDef: 0, //
tEffected: 0, // How many turns the user has been effected by a status effect. 0 if unaffected
image: "N/A", // Generated by Rails and used to determine with jpeg to load
moves: [null] // Sets an empty array for the moves and setting that up is gonna suck so I'm avoiding it
},
opp: {
is_user: false,
name: "",
class_type: null,
id: null, // See Above
hp: 0,
type: null,
level: 0,
status: "none",
spd: 0,
atk: 0,
def: 0,
sAtk: 0,
sDef: 0,
tEffected: 0,
image: "N/A",
moves: [null]
}
},
battle_details: {
turns: 0, // This will keep track of the turns elapsed
whoseTurn_id: null, // This will be set to 'user', 'opp', or 'none'.
this_move_target_id: null,
prompt: "Welcome"
}
}, action
){
if (!action){
console.log("Action is nil")
}
switch (action.type) {
case 'NEW_BATTLE':
// FETCH NEW BATTLE JSON
case 'CHANGE_USER_HP':
// action = {type: "CHANGE_OPP_HP", amount: {Number generated in Event Listener inside of Moves}, effect: {String generated in Event Listener} }
let effect = action.effect
let newUserState = applyingStatusEffectandDamage(state, action.amount, effect)
return {newUserState}
case 'CHANGE_OPP_HP':
// action = {type: "CHANGE_OPP_HP", amount: {Number generated in Event Listener inside of Moves}, effect: {String generated in Event Listener} }
effect = action.effect
let newOppState = applyingStatusEffectandDamage(state, action.amount, effect)
return {newOppState}
case 'COMPLETE_BATTLE':
// CHANGE PROMPT, RESET USER HP, LEVEL UP
default:
return state;
}
};
希望这对你有用。