Reputation: 1672
I've taken two courses, treehouse and one on udemy, on react/redux and just when I think to myself "hey you got this, let's do a little practice" I run into some huge bug I can't seem to diagnose.
What I'm trying to do here sounds very simple, and in plain javascript it works. My state is an empty object state = {}
and when my action is called, it creates an array inside of state noteName
. So at the end of the day state should look like state = { noteName: [ ...state.noteName, action.payload]}
.
When I console.log(this.props.inputvalue)
it will return whatever is in the input
element. I thought I understood objects because that consolelog should return the array noteName
and not the actual value, correct?
actions/index.js
export const INPUT_VALUE = 'INPUT_VALUE';
export function addNoteAction(text) {
return {
type: INPUT_VALUE,
payload: text
}
}
reducers/reducer_inputvalue.js
import { INPUT_VALUE } from '../actions';
// state is initialized as an empty object here
export default function(state = {}, action) {
switch (action.type) {
case INPUT_VALUE:
state.noteName = [];
// this SHOULD create an array that concats action.payload with
// whatever is already inside of state.name
return state.noteName = [...state.noteName, action.payload];
default:
return state;
}
}
noteitems.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
class NoteItems extends Component {
render() {
return (
<ul>
{
this.props.inputvalue.noteName
?
this.props.inputvalue.noteName.map((note, index) => {
// this should iterate through noteName but returns undefined
return <li key={index}>{note}</li>;
})
:
<li>Nothing here</li>
}
</ul>
);
}
}
function mapStateToProps(state) {
return {
inputvalue: state.inputvalue
}
}
export default connect(mapStateToProps)(NoteItems);
Upvotes: 1
Views: 66
Reputation: 2295
This is happening because every time the action INPUT_VALUE
is dispatched, you are resetting noteName
. The main principle of redux is to not modify the state, but creating a new one based on the current. In your case:
const initialState = {
noteName: []
};
export default function(state = initialState, action) {
switch (action.type) {
case INPUT_VALUE: return {
noteName: [...state.noteName, action.payload]
};
default: return state;
}
}
Upvotes: 1
Reputation: 26696
You are overwriting state.noteName
in the first line of your switch case.
switch (action.type) {
case INPUT_VALUE:
state.noteName = [];
In Redux, the point is to never overwrite a value, but to return a new value that might be a brand-new value, might be a value that is based on the old value (but still a new value... not overwriting the old), or it might be returning the old value (completely unmodified).
const counterReducer = (counter, action) => {
const options = {
[COUNTER_INCREMENT]: (counter, action) =>
({ value: counter.value + 1 }),
[COUNTER_DECREMENT]: (counter, action) =>
({ value: counter.value - 1 }),
[COUNTER_RESET]: (counter, action) =>
({ value: 0 })
};
const strategy = options[action.type];
return strategy ? strategy(counter, action) : counter;
};
At no point in that example am I modifying a value on counter
. Everything is treated as read-only.
Upvotes: 0