admin管理员组

文章数量:1355542

I am trying to strike through a list item once a user has clicked on that particular item.

I have created a function to conduct the style change

const pleted = () =>{
     return document.getElementById("demo").style.textDecoration='line-through'
};

The list is generated as below, i have used material ui library

 <List dense={dense} >
      {items.slice(0).reverse().map(x=> (
           <ListItem key={x.id} button id="demo" onClick={pleted} divider>
                 <ListItemText primary={listItems(x)}/>
                 <ListItemSecondaryAction />
           </ListItem>

       ))}                              
</List>

From the code i have written i am able to strike only through the first item of the list. Whenever i add new items , always the only item i am able to strike through is the first item.

I am trying to find a way to apply this to all the elements on the list

I am trying to strike through a list item once a user has clicked on that particular item.

I have created a function to conduct the style change

const pleted = () =>{
     return document.getElementById("demo").style.textDecoration='line-through'
};

The list is generated as below, i have used material ui library

 <List dense={dense} >
      {items.slice(0).reverse().map(x=> (
           <ListItem key={x.id} button id="demo" onClick={pleted} divider>
                 <ListItemText primary={listItems(x)}/>
                 <ListItemSecondaryAction />
           </ListItem>

       ))}                              
</List>

From the code i have written i am able to strike only through the first item of the list. Whenever i add new items , always the only item i am able to strike through is the first item.

I am trying to find a way to apply this to all the elements on the list

Share Improve this question edited Mar 24, 2020 at 3:56 iamhuynq 5,5492 gold badges16 silver badges40 bronze badges asked Mar 24, 2020 at 3:33 George SilvaGeorge Silva 3855 silver badges13 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

It is not a good practice to use document.getElementById() in React because then you are accessing the DOM directly. Instead, you have to use ref.

From official React documentation

When to Use Refs There are a few good use cases for refs:

  • Managing focus, text selection, or media playback.
  • Triggering imperative animations.
  • Integrating with third-party DOM libraries.

But in your case we can easily do this by using React state. I assume that your items is stored in your ponent state and in a todo item, you need to store whether it is pleted or not ( a boolean value ). You can update the code like the following.

const pleted = (id) => {
   /* update the state by changing the pleted value of the
      clicked todo item */
   this.setState({
      items : this.state.items.map(item => {
         if(item.id === id){
            item.pleted = true;
         }
         return item;
      })
   })

}

<List dense={dense}>
  {this.state.items
    .reverse()
    .map(x => (
      <ListItem
        key={x.id}
        button
        // add a unique id
        id={x.id}
        
        // add a strike style depending on the pleted property of the todo item
        style={{ textDecoration : x.pleted ? 'line-through' : 'none' }} 
        
        // call pleted with the id
        onClick={() => pleted(x.id)} 

        divider
      >
        <ListItemText primary={listItems(x)} />
        <ListItemSecondaryAction></ListItemSecondaryAction>
      </ListItem>
    ))}
</List>

Id's should be all unique in HTML. You should add dynamic id-values to each element and send the id in function-call like following.

const pleted = (id) => {
 document.getElementById(id).style.textDecoration='line-through'
}

<List dense={dense}>
  {items
    .slice(0)
    .reverse()
    .map(x => (
      <ListItem
        key={x.id}
        button
        id={x.id} // Add dynamic ID
        onClick={() => pleted(x.id)} // Send ID to function
        divider
      >
        <ListItemText primary={listItems(x)} />
        <ListItemSecondaryAction></ListItemSecondaryAction>
      </ListItem>
    ))}
</List>

本文标签: javascriptStrike through any item in a list created using material ui and ReactjsStack Overflow