Search code examples
reactjsreact-nativereact-state-managementreact-state

Struggling to use the spread operator on style objects. I'm trying to retain multiple properties but can't figure out how to do so cleanly


Classic to-do list project. I'm trying to update the state of my list item when I click on it as well as hover on/off. I'm struggling to retain all my previous properties when the state changes. So far, the only fix has been to specify each property in each function and give it prevValue if I don't want it to change. In my code below, I used this fix with my strikethrough textDecoration to illustrate when it works, but didn't use it for fontStyle and opacity to see what happens when I don't specify it or attempt an alternative method.

I imagine there's a much better way to do this, but I'm struggling to describe it well enough to find a good answer online. I figure it's something to do with the spread operator, but nothing has clicked for me so far. Thanks for your help!

import React, { useState } from "react";
 
function ToDoItem(props) {
  const [textStrike, setStrikeState] = useState(false);
 
  const [textStyle, setTextStyle] = useState({
    key: 0,
    textDecoration: "none",
    fontStyle: "normal",
    opacity: "1"
  });
 
 
 function handleClick(prevValue) {
   
    if (textStrike === false) {
      setTextStyle({  
        textDecoration: "line-through",
        fontStyle: "italic",
        opacity: "0.4"
      })} 
    else {
      setTextStyle({
        textDecoration: "none",
        fontStyle: "normal",
        opacity: "1"
      })}
 
    setStrikeState(prevValue => !prevValue);
    console.log("textStrike boolean value is " + textStrike);
  } 
 
 
 function hoverOnHandle(prevValue) {
   setTextStyle({
     textDecoration: prevValue,
     textShadow: "1px 1px lightgray"
   });
 }
 
 function hoverOffHandle(prevValue) {
   setTextStyle({
     textDecoration: prevValue,
     textShadow: ""
   });
 }
 
 
 return (
   <li
     onClick={handleClick} 
     onMouseOver={hoverOnHandle}
     onMouseOut={hoverOffHandle}
     style={textStyle}
   >
     {props.text}
   </li>
  );
 }
 
export default ToDoItem;

Solution

  • If you want to only update or add certain properties, you can use

    setTextStyle({ 
      ...textStyle,
      yourProperty: yourValue
    }) 
    

    For exmaple, if you want to update only the fontFamily, you can

    setTextStyle({ 
          ...textStyle,
          fontFamily: 'Roboto'
        });