Reputation: 177
I am trying to imitate a behaviour of a checked componenet applied to a map of divs. I am mapping displayName and imageUrl of an array of elements called price. On click of the div, in handleProductSelect function, I would like only the clicked div to be highlighted, however they all become highlighted, which makes sense, because I am collectively making a change in the style.
class App extends Component {
constructor(props) {
super(props);
this.state = {
borderColor: 'white',
}
}
handleProductSelect() {
const { borderColor } = this.state;
let newBorderColour = borderColor === 'white' ? 'blue' : 'white';
this.setState({
borderColor: newBorderColour,
})
}
(price.map(p =>
<div key={p.productId}>
<div
style={{
borderRadius: '10%',
borderStyle: 'solid',
padding: '10px',
marginBottom: 10,
borderColor: this.state.borderColor,
}}
onClick={this.handleProductSelect(p.productId)}>
<div>{p.displayName}</div><br />
<div>{p.imageUrl !== '' ? p.imageUrl : <img style={{ width: '100px', height: '50px' }} src={"https://source.unsplash.com/200/150"} />}</div><br />
</div>
</div>
))
}
Does anyone have any idea on how to make only the clicked element highlighted?
Upvotes: 0
Views: 2464
Reputation: 2231
Here I have fixes the syntax of ternary operator style css, and fatArrow function call with onClick event
class App extends Component {
constructor(props) {
super(props);
this.state = {
borderColor: 'white',
active_id: null
};
}
handleProductSelect(productId) {
const { borderColor } = this.state;
let newBorderColour = borderColor === 'white' ? 'blue' : 'white';
this.setState({
borderColor: newBorderColour,
active_id: productId
})
}
render {
return(
(price.map(p =>
<div key={p.productId}>
<div
style={{
borderRadius: '10%',
borderStyle: 'solid',
padding: '10px',
marginBottom: 10,
p.productId === this.state.active_id ? { borderColor: this.state.borderColor} : {borderColor : 'white'}
}}
onClick={(p)=> this.handleProductSelect(p.productId)}>
<div>{p.displayName}</div><br />
<div>{p.imageUrl !== '' ? p.imageUrl : <img style={{ width: '100px', height: '50px' }} src={"https://source.unsplash.com/200/150"} />}</div><br />
</div>
</div>
))
}
)}
Upvotes: 0
Reputation: 2825
Use the id that you are passing to your handleProductSelect
function and save it to the state. You can use it in the render
method, to figure which one is the clicked element and apply the appropriate style to it
class App extends Component {
constructor(props) {
super(props);
this.state = {
borderColor: 'white',
active_id: null
};
}
handleProductSelect(productId) {
const { borderColor } = this.state;
let newBorderColour = borderColor === 'white' ? 'blue' : 'white';
this.setState({
borderColor: newBorderColour,
active_id: productId
})
}
render {
return(
(price.map(p =>
<div key={p.productId}>
<div
style={{
borderRadius: '10%',
borderStyle: 'solid',
padding: '10px',
marginBottom: 10,
borderColor: ( p.productId === this.state.active_id ? this.state.borderColor : 'white'),
}}
onClick={this.handleProductSelect.bind(this, p.productId)}>
<div>{p.displayName}</div><br />
<div>{p.imageUrl !== '' ? p.imageUrl : <img style={{ width: '100px', height: '50px' }} src={"https://source.unsplash.com/200/150"} />}</div><br />
</div>
</div>
))
}
)}
Upvotes: 1