React redux nested smart component - state isn't mapped to props
I am creating a drinks counter that will count the amount of drinks consumed as part of a project to learn redux.
I have some initial state that has a drinks property that contains a collection of drinks and their current count:
//State
{
drinks: {
coffee: 0,
water: 0,
}
//...
}
I have created a Counter
presentational component:
import React from 'react';
import PropTypes from 'prop-types';
import Button from './Button';
const ucFirst = string => string.charAt(0).toUpperCase() + string.slice(1);
const Counter = ({name, count, onIncrement, onDecrement}) => (
<div className="counter">
<h2>{ucFirst(name)}</h2>
<span>{count}</span>
<Button onClick={() => {onIncrement(name)}}>+</Button>
<Button onClick={() => {onDecrement(name)}}>-</Button>
</div>
);
Counter.propTypes = {
name: PropTypes.string.isRequired,
count: PropTypes.number.isRequired,
onIncrement: PropTypes.func.isRequired,
onDecrement: PropTypes.func.isRequired,
}
export default Counter;
Followed by a DrinkCounter
container component:
import { connect } from 'react-redux'
import { incrementDrink, decrementDrink } from '../actions'
import Counter from '../components/Counter'
const mapStateToProps = (state, ownProps) => ({
count: state.drinks[ownProps.drink],
name: ownProps.drink
})
const mapDispatchToProps = dispatch => ({
onIncrement: drink => dispatch(incrementDrink(drink)),
onDecrement: drink => dispatch(decrementDrink(drink))
})
export default connect(
mapStateToProps,
mapDispatchToProps
)(Counter)
This works as expected, if I add
<DrinksContainer name="coffee" />
into my App
component.
Now this is where the problem begins, I want to create two more components one presentational and one container that will map over the keys of my drinks
object and output a DrinkCounter
for each, I have the following code but I'm getting the error "Failed prop type: The prop name
is marked as required in Counter
, but its value is undefined
"
Here is List
container:
import React, {Fragment} from 'react'
import PropTypes from 'prop-types'
import DrinkCounter from '../containers/DrinkCounter'
const List = ({drinks}) => {
return (
<Fragment>
{
Object.keys(drinks).map(
(drink, index) => (<DrinkCounter name={drink} key={index} />)
)
}
</Fragment>
)
}
List.propTypes = {
drinks: PropTypes.object.isRequired
}
export default List
and here is the DrinksList
container:
import React from 'react';
import {connect} from 'react-redux';
import List from '../components/List';
const mapStateToProps = state => ({
drinks: state.drinks
})
export default connect(mapStateToProps)(List);
Could someone explain where I'm going wrong?
javascript reactjs redux react-redux
|
show 3 more comments
I am creating a drinks counter that will count the amount of drinks consumed as part of a project to learn redux.
I have some initial state that has a drinks property that contains a collection of drinks and their current count:
//State
{
drinks: {
coffee: 0,
water: 0,
}
//...
}
I have created a Counter
presentational component:
import React from 'react';
import PropTypes from 'prop-types';
import Button from './Button';
const ucFirst = string => string.charAt(0).toUpperCase() + string.slice(1);
const Counter = ({name, count, onIncrement, onDecrement}) => (
<div className="counter">
<h2>{ucFirst(name)}</h2>
<span>{count}</span>
<Button onClick={() => {onIncrement(name)}}>+</Button>
<Button onClick={() => {onDecrement(name)}}>-</Button>
</div>
);
Counter.propTypes = {
name: PropTypes.string.isRequired,
count: PropTypes.number.isRequired,
onIncrement: PropTypes.func.isRequired,
onDecrement: PropTypes.func.isRequired,
}
export default Counter;
Followed by a DrinkCounter
container component:
import { connect } from 'react-redux'
import { incrementDrink, decrementDrink } from '../actions'
import Counter from '../components/Counter'
const mapStateToProps = (state, ownProps) => ({
count: state.drinks[ownProps.drink],
name: ownProps.drink
})
const mapDispatchToProps = dispatch => ({
onIncrement: drink => dispatch(incrementDrink(drink)),
onDecrement: drink => dispatch(decrementDrink(drink))
})
export default connect(
mapStateToProps,
mapDispatchToProps
)(Counter)
This works as expected, if I add
<DrinksContainer name="coffee" />
into my App
component.
Now this is where the problem begins, I want to create two more components one presentational and one container that will map over the keys of my drinks
object and output a DrinkCounter
for each, I have the following code but I'm getting the error "Failed prop type: The prop name
is marked as required in Counter
, but its value is undefined
"
Here is List
container:
import React, {Fragment} from 'react'
import PropTypes from 'prop-types'
import DrinkCounter from '../containers/DrinkCounter'
const List = ({drinks}) => {
return (
<Fragment>
{
Object.keys(drinks).map(
(drink, index) => (<DrinkCounter name={drink} key={index} />)
)
}
</Fragment>
)
}
List.propTypes = {
drinks: PropTypes.object.isRequired
}
export default List
and here is the DrinksList
container:
import React from 'react';
import {connect} from 'react-redux';
import List from '../components/List';
const mapStateToProps = state => ({
drinks: state.drinks
})
export default connect(mapStateToProps)(List);
Could someone explain where I'm going wrong?
javascript reactjs redux react-redux
feels like that within yourDrinkCounter
you useCounter
component but you don't passname
property to it.
– dee zg
Nov 24 '18 at 14:22
I know but in theList
component where the map is happening I add thename
prop like this<DrinkCounter name={drink} key={index} />
– mrmadhat
Nov 24 '18 at 14:29
what does yourDrinkCounter
component look like?
– dee zg
Nov 24 '18 at 14:34
The code for theDrinkCounter
component is in the question body
– mrmadhat
Nov 24 '18 at 14:44
well, not really. you're not showing anything but itsmapStateToProps
&mapDispatchToProps
methods. where is the rest?
– dee zg
Nov 24 '18 at 14:45
|
show 3 more comments
I am creating a drinks counter that will count the amount of drinks consumed as part of a project to learn redux.
I have some initial state that has a drinks property that contains a collection of drinks and their current count:
//State
{
drinks: {
coffee: 0,
water: 0,
}
//...
}
I have created a Counter
presentational component:
import React from 'react';
import PropTypes from 'prop-types';
import Button from './Button';
const ucFirst = string => string.charAt(0).toUpperCase() + string.slice(1);
const Counter = ({name, count, onIncrement, onDecrement}) => (
<div className="counter">
<h2>{ucFirst(name)}</h2>
<span>{count}</span>
<Button onClick={() => {onIncrement(name)}}>+</Button>
<Button onClick={() => {onDecrement(name)}}>-</Button>
</div>
);
Counter.propTypes = {
name: PropTypes.string.isRequired,
count: PropTypes.number.isRequired,
onIncrement: PropTypes.func.isRequired,
onDecrement: PropTypes.func.isRequired,
}
export default Counter;
Followed by a DrinkCounter
container component:
import { connect } from 'react-redux'
import { incrementDrink, decrementDrink } from '../actions'
import Counter from '../components/Counter'
const mapStateToProps = (state, ownProps) => ({
count: state.drinks[ownProps.drink],
name: ownProps.drink
})
const mapDispatchToProps = dispatch => ({
onIncrement: drink => dispatch(incrementDrink(drink)),
onDecrement: drink => dispatch(decrementDrink(drink))
})
export default connect(
mapStateToProps,
mapDispatchToProps
)(Counter)
This works as expected, if I add
<DrinksContainer name="coffee" />
into my App
component.
Now this is where the problem begins, I want to create two more components one presentational and one container that will map over the keys of my drinks
object and output a DrinkCounter
for each, I have the following code but I'm getting the error "Failed prop type: The prop name
is marked as required in Counter
, but its value is undefined
"
Here is List
container:
import React, {Fragment} from 'react'
import PropTypes from 'prop-types'
import DrinkCounter from '../containers/DrinkCounter'
const List = ({drinks}) => {
return (
<Fragment>
{
Object.keys(drinks).map(
(drink, index) => (<DrinkCounter name={drink} key={index} />)
)
}
</Fragment>
)
}
List.propTypes = {
drinks: PropTypes.object.isRequired
}
export default List
and here is the DrinksList
container:
import React from 'react';
import {connect} from 'react-redux';
import List from '../components/List';
const mapStateToProps = state => ({
drinks: state.drinks
})
export default connect(mapStateToProps)(List);
Could someone explain where I'm going wrong?
javascript reactjs redux react-redux
I am creating a drinks counter that will count the amount of drinks consumed as part of a project to learn redux.
I have some initial state that has a drinks property that contains a collection of drinks and their current count:
//State
{
drinks: {
coffee: 0,
water: 0,
}
//...
}
I have created a Counter
presentational component:
import React from 'react';
import PropTypes from 'prop-types';
import Button from './Button';
const ucFirst = string => string.charAt(0).toUpperCase() + string.slice(1);
const Counter = ({name, count, onIncrement, onDecrement}) => (
<div className="counter">
<h2>{ucFirst(name)}</h2>
<span>{count}</span>
<Button onClick={() => {onIncrement(name)}}>+</Button>
<Button onClick={() => {onDecrement(name)}}>-</Button>
</div>
);
Counter.propTypes = {
name: PropTypes.string.isRequired,
count: PropTypes.number.isRequired,
onIncrement: PropTypes.func.isRequired,
onDecrement: PropTypes.func.isRequired,
}
export default Counter;
Followed by a DrinkCounter
container component:
import { connect } from 'react-redux'
import { incrementDrink, decrementDrink } from '../actions'
import Counter from '../components/Counter'
const mapStateToProps = (state, ownProps) => ({
count: state.drinks[ownProps.drink],
name: ownProps.drink
})
const mapDispatchToProps = dispatch => ({
onIncrement: drink => dispatch(incrementDrink(drink)),
onDecrement: drink => dispatch(decrementDrink(drink))
})
export default connect(
mapStateToProps,
mapDispatchToProps
)(Counter)
This works as expected, if I add
<DrinksContainer name="coffee" />
into my App
component.
Now this is where the problem begins, I want to create two more components one presentational and one container that will map over the keys of my drinks
object and output a DrinkCounter
for each, I have the following code but I'm getting the error "Failed prop type: The prop name
is marked as required in Counter
, but its value is undefined
"
Here is List
container:
import React, {Fragment} from 'react'
import PropTypes from 'prop-types'
import DrinkCounter from '../containers/DrinkCounter'
const List = ({drinks}) => {
return (
<Fragment>
{
Object.keys(drinks).map(
(drink, index) => (<DrinkCounter name={drink} key={index} />)
)
}
</Fragment>
)
}
List.propTypes = {
drinks: PropTypes.object.isRequired
}
export default List
and here is the DrinksList
container:
import React from 'react';
import {connect} from 'react-redux';
import List from '../components/List';
const mapStateToProps = state => ({
drinks: state.drinks
})
export default connect(mapStateToProps)(List);
Could someone explain where I'm going wrong?
//State
{
drinks: {
coffee: 0,
water: 0,
}
//...
}
//State
{
drinks: {
coffee: 0,
water: 0,
}
//...
}
import React from 'react';
import PropTypes from 'prop-types';
import Button from './Button';
const ucFirst = string => string.charAt(0).toUpperCase() + string.slice(1);
const Counter = ({name, count, onIncrement, onDecrement}) => (
<div className="counter">
<h2>{ucFirst(name)}</h2>
<span>{count}</span>
<Button onClick={() => {onIncrement(name)}}>+</Button>
<Button onClick={() => {onDecrement(name)}}>-</Button>
</div>
);
Counter.propTypes = {
name: PropTypes.string.isRequired,
count: PropTypes.number.isRequired,
onIncrement: PropTypes.func.isRequired,
onDecrement: PropTypes.func.isRequired,
}
export default Counter;
import React from 'react';
import PropTypes from 'prop-types';
import Button from './Button';
const ucFirst = string => string.charAt(0).toUpperCase() + string.slice(1);
const Counter = ({name, count, onIncrement, onDecrement}) => (
<div className="counter">
<h2>{ucFirst(name)}</h2>
<span>{count}</span>
<Button onClick={() => {onIncrement(name)}}>+</Button>
<Button onClick={() => {onDecrement(name)}}>-</Button>
</div>
);
Counter.propTypes = {
name: PropTypes.string.isRequired,
count: PropTypes.number.isRequired,
onIncrement: PropTypes.func.isRequired,
onDecrement: PropTypes.func.isRequired,
}
export default Counter;
import { connect } from 'react-redux'
import { incrementDrink, decrementDrink } from '../actions'
import Counter from '../components/Counter'
const mapStateToProps = (state, ownProps) => ({
count: state.drinks[ownProps.drink],
name: ownProps.drink
})
const mapDispatchToProps = dispatch => ({
onIncrement: drink => dispatch(incrementDrink(drink)),
onDecrement: drink => dispatch(decrementDrink(drink))
})
export default connect(
mapStateToProps,
mapDispatchToProps
)(Counter)
import { connect } from 'react-redux'
import { incrementDrink, decrementDrink } from '../actions'
import Counter from '../components/Counter'
const mapStateToProps = (state, ownProps) => ({
count: state.drinks[ownProps.drink],
name: ownProps.drink
})
const mapDispatchToProps = dispatch => ({
onIncrement: drink => dispatch(incrementDrink(drink)),
onDecrement: drink => dispatch(decrementDrink(drink))
})
export default connect(
mapStateToProps,
mapDispatchToProps
)(Counter)
import React, {Fragment} from 'react'
import PropTypes from 'prop-types'
import DrinkCounter from '../containers/DrinkCounter'
const List = ({drinks}) => {
return (
<Fragment>
{
Object.keys(drinks).map(
(drink, index) => (<DrinkCounter name={drink} key={index} />)
)
}
</Fragment>
)
}
List.propTypes = {
drinks: PropTypes.object.isRequired
}
export default List
import React, {Fragment} from 'react'
import PropTypes from 'prop-types'
import DrinkCounter from '../containers/DrinkCounter'
const List = ({drinks}) => {
return (
<Fragment>
{
Object.keys(drinks).map(
(drink, index) => (<DrinkCounter name={drink} key={index} />)
)
}
</Fragment>
)
}
List.propTypes = {
drinks: PropTypes.object.isRequired
}
export default List
import React from 'react';
import {connect} from 'react-redux';
import List from '../components/List';
const mapStateToProps = state => ({
drinks: state.drinks
})
export default connect(mapStateToProps)(List);
import React from 'react';
import {connect} from 'react-redux';
import List from '../components/List';
const mapStateToProps = state => ({
drinks: state.drinks
})
export default connect(mapStateToProps)(List);
javascript reactjs redux react-redux
javascript reactjs redux react-redux
asked Nov 24 '18 at 14:18
mrmadhatmrmadhat
85
85
feels like that within yourDrinkCounter
you useCounter
component but you don't passname
property to it.
– dee zg
Nov 24 '18 at 14:22
I know but in theList
component where the map is happening I add thename
prop like this<DrinkCounter name={drink} key={index} />
– mrmadhat
Nov 24 '18 at 14:29
what does yourDrinkCounter
component look like?
– dee zg
Nov 24 '18 at 14:34
The code for theDrinkCounter
component is in the question body
– mrmadhat
Nov 24 '18 at 14:44
well, not really. you're not showing anything but itsmapStateToProps
&mapDispatchToProps
methods. where is the rest?
– dee zg
Nov 24 '18 at 14:45
|
show 3 more comments
feels like that within yourDrinkCounter
you useCounter
component but you don't passname
property to it.
– dee zg
Nov 24 '18 at 14:22
I know but in theList
component where the map is happening I add thename
prop like this<DrinkCounter name={drink} key={index} />
– mrmadhat
Nov 24 '18 at 14:29
what does yourDrinkCounter
component look like?
– dee zg
Nov 24 '18 at 14:34
The code for theDrinkCounter
component is in the question body
– mrmadhat
Nov 24 '18 at 14:44
well, not really. you're not showing anything but itsmapStateToProps
&mapDispatchToProps
methods. where is the rest?
– dee zg
Nov 24 '18 at 14:45
feels like that within your
DrinkCounter
you use Counter
component but you don't pass name
property to it.– dee zg
Nov 24 '18 at 14:22
feels like that within your
DrinkCounter
you use Counter
component but you don't pass name
property to it.– dee zg
Nov 24 '18 at 14:22
I know but in the
List
component where the map is happening I add the name
prop like this <DrinkCounter name={drink} key={index} />
– mrmadhat
Nov 24 '18 at 14:29
I know but in the
List
component where the map is happening I add the name
prop like this <DrinkCounter name={drink} key={index} />
– mrmadhat
Nov 24 '18 at 14:29
what does your
DrinkCounter
component look like?– dee zg
Nov 24 '18 at 14:34
what does your
DrinkCounter
component look like?– dee zg
Nov 24 '18 at 14:34
The code for the
DrinkCounter
component is in the question body– mrmadhat
Nov 24 '18 at 14:44
The code for the
DrinkCounter
component is in the question body– mrmadhat
Nov 24 '18 at 14:44
well, not really. you're not showing anything but its
mapStateToProps
& mapDispatchToProps
methods. where is the rest?– dee zg
Nov 24 '18 at 14:45
well, not really. you're not showing anything but its
mapStateToProps
& mapDispatchToProps
methods. where is the rest?– dee zg
Nov 24 '18 at 14:45
|
show 3 more comments
1 Answer
1
active
oldest
votes
I have figured out the problem, in the List
component I am giving the wrong prop to DrinkCounter
I'm passing name
when actually it should be drink
.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53459072%2freact-redux-nested-smart-component-state-isnt-mapped-to-props%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I have figured out the problem, in the List
component I am giving the wrong prop to DrinkCounter
I'm passing name
when actually it should be drink
.
add a comment |
I have figured out the problem, in the List
component I am giving the wrong prop to DrinkCounter
I'm passing name
when actually it should be drink
.
add a comment |
I have figured out the problem, in the List
component I am giving the wrong prop to DrinkCounter
I'm passing name
when actually it should be drink
.
I have figured out the problem, in the List
component I am giving the wrong prop to DrinkCounter
I'm passing name
when actually it should be drink
.
answered Nov 24 '18 at 20:34
mrmadhatmrmadhat
85
85
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53459072%2freact-redux-nested-smart-component-state-isnt-mapped-to-props%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
feels like that within your
DrinkCounter
you useCounter
component but you don't passname
property to it.– dee zg
Nov 24 '18 at 14:22
I know but in the
List
component where the map is happening I add thename
prop like this<DrinkCounter name={drink} key={index} />
– mrmadhat
Nov 24 '18 at 14:29
what does your
DrinkCounter
component look like?– dee zg
Nov 24 '18 at 14:34
The code for the
DrinkCounter
component is in the question body– mrmadhat
Nov 24 '18 at 14:44
well, not really. you're not showing anything but its
mapStateToProps
&mapDispatchToProps
methods. where is the rest?– dee zg
Nov 24 '18 at 14:45