Search code examples
javascriptarraysreactjsstatesplice

Removing elements from array by clicking on them in React


I have an array of messages, that are rendered into react components with array.map and key=index (in array). The array is saved to a state. I would like the messages to close, when I click on the button in the message component. I thought about passing the key variable to the Messages Component so I could use it in the closeMessage function by calling target.key somehow, but when I call the the key attribute I only get undefined. Any idea how I can do this? Thanks in advance!

function Register () {

const [errors, setErrors] = useState([{ msg: 'abc' }, { msg: 'cde' }]);

const closeMessage = ({target}) => {
        setErrors(errors => errors.splice(target.key, 1));
    }

return (
<div className="register-container">
    <h1>Register</h1>
    {errors.map((error, index) => <Messages alert="warning" msg={error.msg} key={index} close={closeMessage}/>)}
</div>
)
};
function Messages (props) {

    return(
        <div className={'message '+props.alert} key={props.key} onClick={props.close}>
            {props.msg}
            <button type="button" className="message-close">
                <span>&times;</span>
            </button>
        </div>
    )
}

Solution

  • The passing of the key attribute in your code is not correct. That's why you are getting the undefined value. Rather you can pass the index directly to the closeMessage() function.

    And in case of removing the message you can use either slice() method or the filter() method. I am giving an example using the filter() method according to your code sample:

    function Register () {
    
        const [errors, setErrors] = useState([{ msg: 'abc' }, { msg: 'cde' }]);
    
        const closeMessage = (key) => {
            setErrors(errors => errors.filter((item, index) => key !== index);
        }
    
        return (
           <div className="register-container">
             <h1>Register</h1>
             {errors.map((error, index) => <Messages alert="warning" msg={error.msg} key={index} close={() => closeMessage(index)}/>)}
           </div>
        )
     };