简体   繁体   中英

How To Manipulate One Element Without Effecting The others in Array.map(), REACT.JS

I want to change the styling of an element when a button is clicked, but I can't figure out how to do so without changing the styles of all the elements in the array that haven't been clicked.

        <div >
            {props.stuff.map(item => 
                <li className={itemClass}>
                    <div>{item}</div>
                    <button onClick={...change the style of the <li> without effecting the others}>Done</button>
                </li>)}
        </div>

I'm thinking I need to give each li a unique ID and access that ID in my click Handler function and apply another css class to only the li with that ID... except I can't figure out how to do that. Or I could be going in the wrong direction. Any suggestions would be very much appreciated!

You can try something like this:

const handleClick=(e)=>{
        e.preventDefault();
        e.target.style.color = 'red'
    }

<button onClick={(e) => handleClick(e)}>Done</button>

Not sure this is " the best way " as I'm not a front-end developer myself, but you could create the li as a separated component then use React's useState hook. For example:

/* your file */
<div>
  {props.stuff.map(item => <MagicLi>{item}</MagicLi>)}
</div>
/* separated component file */
import React, { useState } from 'react';

function MagicLi(props) {
  
  const [color, setColor] = useState('li-orange');

  const changeColor = function() {
    if (color === 'li-orange') setColor('li-green');
    else setColor('li-orange');
  };

  return (
    <li className={color}>
      <div>{props.children}</div>
      <button onClick={changeColor}>Done</button>
    </li>
  );
}

export default MagicLi;
/* add to your css file the styling you want */
.li-orange {
  color: orange;
}

.li-green {
  color: green;
}

Since you're iterating over the set via stuff.map you can apply a conditional style to the desired element. No id is required.

For example:

const [clickedIndex, setClickedIndex] = useState(null)
const specialStyle = { ...someStyles }

<div >
  {props.stuff.map((item, index) => 
    <li className={itemClass} style={index === clickedIndex ? specialStyle: null}>
      <div>{item}</div>
      <button onClick={() => setClickedIndex(index)}>Done</button>
    </li>)}
</div>

To expand on the above answer, it is limited to one special-colored li tag. If every li tag needs to track it's own special color state, then a new component would be a good approach that renders one li and tracks it's own state.

For example:

{props.stuff.map((item, index) => <CustomLI key={index}/>)

const CustomLi = (props) {
   ... state & render stuff
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM