Reputation: 83
The thing is to get a clickable html tags made from an array mapped and only clicked element triggered by the onClick event:
class Elements extends Component {
constructor(props) {
super(props);
this.state = {
backgroundColor: 'pink'
}
}
click = (e, i) => {
this.setState({
backgroundColor: 'blue'
});
}
render() {
let buttons = ['one','two','three','four'];
return (
<div>
{
buttons.map( (e, index) => {
return (
<button key={index}
style={this.state.style}
onClick={this.click}> {e} </button>
// e => this.click(e, i)?
);
} )
}
</div>
)
}
}
this probably can be resolved by using e.currentTarget.style.... or using onClick method with individual option (here 'i') transmitted but I don't understand the logic behind these methods and don't know how to apply them correctly. Anybody?
Upvotes: 1
Views: 1752
Reputation: 112777
You could keep an an object in your state named e.g. backgroundColors
that contains key/value pairs representing a button and its background color. If the button doesn't have a key in this object, you can fallback to pink
.
You can use a new inline arrow function to send the button name to the event handler, like you outlined in your comment.
Example
class Elements extends React.Component {
constructor(props) {
super(props);
this.state = {
buttons: ["one", "two", "three", "four"],
backgroundColors: {}
};
}
click = button => {
this.setState(prevState => ({
backgroundColors: {
...prevState.backgroundColors,
[button]: "blue"
}
}));
};
render() {
const { buttons, backgroundColors } = this.state;
return (
<div>
{buttons.map(button => {
return (
<button
key={button}
style={{ backgroundColor: backgroundColors[button] || "pink" }}
onClick={() => this.click(button)}
>
{button}
</button>
);
})}
</div>
);
}
}
ReactDOM.render(<Elements />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
You could also use a data-*
property if you absolutely don't want to use a new inline function in the render method.
Example
class Elements extends React.Component {
constructor(props) {
super(props);
this.state = {
buttons: ["one", "two", "three", "four"],
backgroundColors: {}
};
}
click = event => {
const { button } = event.target.dataset;
this.setState(prevState => ({
backgroundColors: {
...prevState.backgroundColors,
[button]: "blue"
}
}));
};
render() {
const { buttons, backgroundColors } = this.state;
return (
<div>
{buttons.map(button => {
return (
<button
key={button}
style={{ backgroundColor: backgroundColors[button] || "pink" }}
data-button={button}
onClick={this.click}
>
{button}
</button>
);
})}
</div>
);
}
}
ReactDOM.render(<Elements />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Upvotes: 1