My Redux App won't even render the first component (App.js) as it keeps erroring. At some point, it's firing the reducer (shown below) with no action, so when the compiler reaches the line switch(action.type)
it keeps thinking action is null and thus it cannot find the type
property anywhere. In fact, I have a console.log as the very first line of a function that is called right away when App.js is rendered that does not even fire, which means the code breaks before it even renders a single component. Keep in mind I have the <Provider />
tags set up in index.js
which renders App.js
------------------------REDUCER--------------------------
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);
It's the this.testPlease()
function that is not being hit, and I can tell that action = nil in the reducers when it's called because if (!action){console.log("Action is nil")}
keeps getting hit every time I try to start the app. npm start
is also flagging me for a few minute warnings, but nothing I think could be affecting this; no actual errors are being generated anywhere but the browser
Your reducer function needs order the state
first and action
after.
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;
}
};
Hope this works for you.