Reputation: 65
I'm having trouble understanding how to access props defined outside of a class component in React.
In the following code all props are defined except for this.props.checkboxArray which currently returns "cannot read property 'props' of undefined."
I know 'this' is not defined outside of the class component so I have tried binding 'this' to checkboxArray but still the same error that 'props' is undefined.
let checkboxObject = this.props.checkboxArray.reduce(
(name, boolean) => ({
...name,
[boolean]: false
}),
{}
);
class CheckboxList extends Component {
constructor(props) {
super(props);
this.state = { checkbox: checkboxObject };
this.checkboxArray = this.checkboxArray.bind(this);
}
handleCheckboxChange = name => {
let checkbox = this.state.checkbox;
for (var key in checkbox) {
if (key === name) {
checkbox[key] = !checkbox[key];
}
}
this.setState({ checkbox });
};
render() {
return (
<div className="row" id="CheckboxList">
{this.props.checkBoxArray.map(checkbox => (
<Checkbox
label={checkbox}
isSelected={checkboxObject[checkbox]}
onCheckboxChange={this.props.onCheckboxTick}
key={checkbox}
/>
))}
</div>
);
}
}
export default CheckboxList;
Upvotes: 5
Views: 10202
Reputation: 790
You should create a function to call checkboxObject like:
const createCheckboxes = checkboxArray => checkboxArray.reduce(
(name, boolean) => ({
...name,
[boolean]: false
}),
{}
);
and call this funtion on your class component: createCheckboxes(this.props.checkboxArray)
Btw, this is not the best practice. Your checkbox should be editted on it's parent component using Selector
Upvotes: 2
Reputation: 34014
You no need to create checkboxObject outside component instead what you can do is that do the reduce of checkboxArray directly in constructor while initializing checkbox state like I did in below updated code. Then access it using this.state.checkbox[checkbox] to isSelected prop
This way you are initialing checkbox state only once Here is the updated code
class CheckboxList extends Component {
constructor(props) {
super(props);
this.state = {
checkbox: this.props.checkboxArray.reduce(
(name, boolean) => ({
...name,
[boolean]: false
}),
{}
); //here you can directly initialize the state
};
this.checkboxArray = this.checkboxArray.bind(this);
}
handleCheckboxChange = name => {
let checkbox = this.state.checkbox;
for (var key in checkbox) {
if (key === name) {
checkbox[key] = !checkbox[key];
}
}
this.setState({ checkbox });
};
render() {
return (
<div className="row" id="CheckboxList">
{this.props.checkBoxArray.map(checkbox => (
<Checkbox
label={checkbox}
isSelected={this.state.checkbox[checkbox]}
onCheckboxChange={this.props.onCheckboxTick}
key={checkbox}
/>
))}
</div>
);
}
}
export default CheckboxList;
Upvotes: 2