Reputation: 93
I was practicing a React and tried to build Arya's kill list. I played around and implemented some features, one supposed to change a person when double clicked. In state I have array (list of people) of array <--- and I want to setState to this array.
I tried to use a ternary operator which suppose to change state from false to true and opposite. But it doesn't work.
Here are examples of a code with solutions I tried to implement:
class App extends React.Component {
state = {
toKill: [
{ name: 'Cersei Lannister',
formDouble: false
},
{ name: 'Ser Ilyn Payne',
formDouble: false
},
{ name: 'The Mountain',
formDouble: false
},
{ name: 'The Hound',
formDouble: false
}
],
}
doubleClickHandler = (index) => {
this.setState({
toKill: this.state.toKill.map(obj =>
obj[index].formDouble ? false : true)
})
// console.log(this.state.toKill[index].formDouble)
// this.state.toKill[index].formDouble === false ?
// this.setState({
// [this.state.toKill[index].formDouble]: true
// }) : this.setState({
// [this.state.toKill[index].formDouble]: false
// })
}
(...)
<div>
{this.state.toKill.map((toKill, index) => {
return <ToKill
double ={() => this.doubleClickHandler(index)}
formDouble={toKill.formDouble}
click ={() => this.deleteToKillHandler(index)}
key={index + toKill.name}
name={toKill.name}
cause={toKill.cause}
img={toKill.img} />
})}
</div>
In doubleClickHandler you can see what I tried to implement and it didn't work.
Here is toKill component:
const ToKill = (props) => {
return (
<div className="hero-card" onDoubleClick={props.double}>
{props.formDouble !== true? <h1>test</h1>
: <>
<div className="hero-img-container">
<img
src={props.img}
alt={props.name}
className="hero-img"
/>
</div>
<div className="hero-desc">
<h3 className="hero-name">{props.name}</h3>
<p className="hero-cause">{props.cause}</p>
<button onClick={props.click}>Delete</button>
</div>
</>
}
</div>
)
}
So what I expect is once I double click on a specific element for example 'The mountain' it will show me it's profile while the rest will show <h1>test</h1>
.
Upvotes: 3
Views: 86
Reputation: 11848
Most probably your doubleClickHandler
is incorrect. As I understand you want to set formDouble
to true
for only single element, which you've clicked. In such case doubleClickHandler
should be
doubleClickHandler = (index) => {
this.setState({
toKill: this.state.toKill.map((obj, objIndex) =>
objIndex === index ? {...obj, formDouble: true} : {...obj, formDouble: false})
})
}
A snippet using this code:
class App extends React.Component {
state = {
toKill: [
{ name: "Cersei Lannister", formDouble: false },
{ name: "Ser Ilyn Payne", formDouble: false },
{ name: "The Mountain", formDouble: false },
{ name: "The Hound", formDouble: false }
]
};
doubleClickHandler = index => {
this.setState({
toKill: this.state.toKill.map((obj, objIndex) =>
objIndex === index
? { ...obj, formDouble: true }
: { ...obj, formDouble: false }
)
});
};
render() {
return (
<div>
{this.state.toKill.map((toKill, index) => {
return (
<ToKill
double={() => this.doubleClickHandler(index)}
formDouble={toKill.formDouble}
click={() => this.deleteToKillHandler(index)}
key={index + toKill.name}
name={toKill.name}
cause={toKill.cause}
img={toKill.img}
/>
);
})}
</div>
);
}
}
const ToKill = props => {
return (
<div className="hero-card" onDoubleClick={props.double}>
{props.formDouble !== true ? (
<h1>test</h1>
) : (
<React.Fragment>
<div className="hero-img-container">
<img src={props.img} alt={props.name} className="hero-img" />
</div>
<div className="hero-desc">
<h3 className="hero-name">{props.name}</h3>
<p className="hero-cause">{props.cause}</p>
<button onClick={props.click}>Delete</button>
</div>
</React.Fragment>
)}
</div>
);
};
ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
Upvotes: 5