I defined a state variable named fullText
.
fullText
The default value is false
.
When the full text is clicked, I want to invert my state value and enable the text to close and open. But when clicked, the text of all rows in the table opens, how can I make it row-specific?
{ !this.state.fullText ? <div onClick={() => this.setState({ fullText: !this.state.fullText })} className="text-primary cursor-pointer font-size-14 mt-2 px-2" key={props.data?.id}> Full Text </div> : <> <div onClick={() => this.setState({ fullText: !this.state.fullText })}className="text-primary cursor-pointer font-size-14 mt-2 px-2" key={props.data?.id}> Short Text </div> <span>{ props.data?.caption}</span> </> }
P粉1988143722024-02-27 16:05:28
It seems that the code example in the question is repeated for every line, but only 1 state fullText
(showMore
in CodeSandbox) is common to all of them. So they all turn on or off together.
If you want each row to have separate open/close functionality, then you need 1 such state per row. A simple solution might be to embed this status into each row's data:
export default class App extends Component { state = { data: [ { id: 1, description: "aaaaa", showMore: false // Initially closed }, // etc. ] }; render() { return ( <> {this.state.data.map((e) => ( <> { /* Read the showMore state of the row, instead of a shared state */ e.showMore === false ? (this.setState({ data: changeShow(this.state.data, e.id, true) })}> Show description{" "}) : ( <>this.setState({ data: changeShow(this.state.data, e.id, false) })}> Show less{" "}{e.description} > )} > ))} > ); } } /*** Update the showMore property of the * row with the given id.*/ function changeShow(data, id, show) { for (const row of data) { if (row.id === id) { // Find the matching row id row.showMore = show; // Update the property } } return data; }