Props are undefined in React

The name of the pictureThe name of the pictureThe name of the pictureClash 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;





You cannot get the props of a component from a DOM node.
– Tholle
Aug 6 at 14:07





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.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard