I'm currently following a tutorial on React and am interested as to how this is possible:
class Counters extends Component {
state = {
counters: [
{ id: 0, value: 0 },
{ id: 1, value: 4 },
{ id: 2, value: 5 },
{ id: 3, value: 9 },
],
};
handleDelete = (counterID) => {
console.log("Event handler called", counterID);
const counters = this.state.counters.filter((c) => c.id !== counterID);
this.setState({ counters });
};
render() {
return (
<React.Fragment>
{this.state.counters.map((counters) => (
<Counter
key={counters.id}
counters={counters}
onDelete={this.handleDelete}
></Counter>
))}
</React.Fragment>
);
}
I am using the "Counters" to keep track of my individual "Counter" (notice the singular noun) components. I am interested to know why is it that I can simply pass the entire array as a prop into "Counter" with this line:
counters={counters}
and with the following code in the "Counter" class:
class Counter extends Component {
state = {
value: this.props.counters.value,
tags: ["tag1", "tag2", "tag3"],
};
styles = {
fontSize: "50px",
fontWeight: "bolder",
};
handleIncrement() {
console.log("Increment clicked.");
this.setState({ value: this.state.count 1 });
}
render() {
console.log(this.props);
return (
<React.Fragment>
<h4>Counter #{this.props.counters.id}</h4>
<span style={{ fontSize: "25px" }} className={this.getBadgeClasses()}>
{this.formatCount()}
</span>
<button
onClick={() => this.handleIncrement()}
className="btn btn-secondary btn-sm m-2"
>
Increment
</button>
<button
onClick={() => this.props.onDelete(this.props.counters.id)}
className="btn btn-danger btn-sm m-2"
>
Delete
</button>
{this.renderTags()}
</React.Fragment>
);
}
getTags() {
let tags = this.state.tags;
return tags === undefined || tags.length <= 0 ? (
<p>"The tag list is empty."</p>
) : (
tags.map((tag) => <li key={tag}>{tag}</li>)
);
}
renderTags() {
return <ul>{this.getTags()}</ul>;
}
getBadgeClasses() {
let classes = "badge m-2 badge-";
classes = this.state.value === 0 ? "warning" : "primary";
return classes;
}
formatCount() {
const value = this.state.value;
return value === 0 ? "Zero" : value;
}
}
export default Counter;
I am able to get an entire list of "Counter" components rendered? I was under the impression I only declared a single in the "Counters" class, yet by passing a list I am able to render an entire list of Counters. How is this possible? What concept am I missing here?
CodePudding user response:
If you want past the entire list on Counter component :
counters={this.state.counters}
Because with counter={counters} you past in fact one element (method map send on item by one item). So in fact, when you write this.state.counters.map((counters) => ..., you should write this.state.counters.map((counter) =>... because it's just one element of array counters.