Props are undefined in React
Clash Royale CLAN TAG#URR8PPP
Props are undefined in React
I'm new to js
and reactjs
. I'm trying to create a ButtonGroup
with few Buttons
inside, in hope of when I click a particular Button
(in ButtonGroup
) only that particular button will get highlighted (change colour) and rest will be of normal colour.
Below is the code which does the above behaviour but in setColour
method I'm getting an error _this.state.selected.props is undefined
. Could someone point out the where I'm getting wrong ? Also, if someone can tell me if this is the correct way to approach this problem.
js
reactjs
ButtonGroup
Buttons
Button
ButtonGroup
setColour
_this.state.selected.props is undefined
import React from "react"
import
ButtonGroup,
Button
from "reactstrap"
class MainButtonsGroup extends React.Component
constructor (props)
super(props)
this.state =
selected: null
handleSelection = (e) =>
this.setState(selected: e.target)
setColour = (key) =>
if (this.state.selected)
// ERROR : _this.state.selected.props is undefined
return (this.state.selected.props.key === key) ? 'primary' : 'secondary'
render()
return (
<ButtonGroup>
<Button key=1 onClick=this.handleSelection color=this.setColour(1)>MainButtonA</Button>
<Button key=2 onClick=this.handleSelection color=this.setColour(2)>MainButtonB</Button>
<Button key=3 onClick=this.handleSelection color=this.setColour(3)>MainButtonC</Button>
</ButtonGroup>
)
export default MainButtonsGroup;
e.target
is the underlying DOM element of the event target. Also, keys are supposed to be used exclusively and internally by React, instead keep a record of the current selection in state. You can pass an index to handleSelection
and set in state– Li357
Aug 6 at 14:07
e.target
handleSelection
Just
this.props.key
– Imanali Mamadiev
Aug 6 at 14:07
this.props.key
You should try to achieve this with css. Set a particular className on a Button based on this.state.selected. Check out github.com/JedWatson/classnames for some ideas and also using that library isn't a bad idea.
– seminull
Aug 6 at 14:14
From the react docs, reactjs.org/docs/events.html you cannot access the event in an asynchronous way.
// Won't work. this.state.clickEvent will only contain null values. this.setState(clickEvent: event);
– Fernando Avalos
Aug 6 at 14:18
// Won't work. this.state.clickEvent will only contain null values. this.setState(clickEvent: event);
2 Answers
2
You should not hold on to the e.target reference and you must be getting a React warning in your console about it? You just created a memory leak in your app.
Instead copy what you need from the target and let the reference be garbage collected. Although in your case there's no need to be attaching data to the DOM node:
<Button onClick=() => this.handleSelection(this.setColour(3))>MainButtonC</Button>
Note you don't need key=3
unless you're mapping the elements in a loop.
key=3
handleSelection = (color) =>
this.setState( selected: color )
However this code is a bit strange, just record the index of the clicked button and give it a class to style it e.g.
class MainButtonsGroup extends React.Component
state =
selectedIndex: null,
handleSelection = (index) =>
this.setState(selectedIndex: index)
render()
const idx = this.state.selectedIndex;
return (
<ButtonGroup>
<Button className=idx === 1 ? 'primary' : 'secondary' onClick=() => this.handleSelection(1)>MainButtonA</Button>
<Button className=idx === 2 ? 'primary' : 'secondary' onClick=() => this.handleSelection(2)>MainButtonB</Button>
<Button className=idx === 3 ? 'primary' : 'secondary' onClick=() => this.handleSelection(3)>MainButtonC</Button>
</ButtonGroup>
);
thanks for your response ! I don't have much reputation to up vote the answer therefore this comment.
– DDStackoverflow
Aug 6 at 15:28
You cannot get the props of a component from a DOM node. You could instead keep your button names in an array in your component state and use that to render your buttons in the render method.
You can then pass in the button name to the handleSelection
and use that as your selected
value. If your button is the selected one it can be given the primary
color, otherwise the secondary
one.
handleSelection
selected
primary
secondary
Example
import React from "react";
import ReactDOM from "react-dom";
import ButtonGroup, Button from "reactstrap";
import "bootstrap/dist/css/bootstrap.min.css";
class MainButtonsGroup extends React.Component
constructor(props)
super(props);
this.state =
buttons: ["A", "B", "C"],
selected: null
;
handleSelection = button =>
this.setState( selected: button );
;
render()
const buttons, selected = this.state;
return (
<ButtonGroup>
buttons.map(button => (
<Button
key=button
onClick=() => this.handleSelection(button)
color=selected === button ? "primary" : "secondary"
>
MainButtonbutton
</Button>
))
</ButtonGroup>
);
thanks for your response ! I don't have much reputation to up vote the answer therefore this comment.
– DDStackoverflow
Aug 6 at 15:28
Sorry didn't mention it, but button names would come from
this.props
so probably, we don't need them part of this.state
.– DDStackoverflow
Aug 6 at 15:31
this.props
this.state
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
You cannot get the props of a component from a DOM node.
– Tholle
Aug 6 at 14:07