'useMemo to set component style

I have a function called styling where I check the value of the parameters to return a color for Card component. A friend told me to try using useMemo to only run the function when my parameters change, but I can't find a way to understand this hook. How would I pass the condition which it doesn't need to run the function?

function styling(votes) {
  let styling = '#696969'

  if (votes > 0) {
    styling = '#008000'
  } else if (votes < 0) {
    styling = '#B22222'
  }

  return styling
}


function App() {

  const [content, setContent] = useState(images)

  const upVote = (param) => {
    setContent(() => {
      for(let i = 0; i < content.length; i++) {
        if (content[i].id === param){
          content[i].votes = content[i].votes+1
        } 
      }
      return [...content]
    })
  }

  const downVote = (param) => {
    setContent(() => {
      for(let i = 0; i < content.length; i++) {
        if (content[i].id === param){
          content[i].votes = content[i].votes-1
        } 
      }
      return [...content]
    })
  }

  

  return (
    <div className="App">
      <div className="grid">
        {content.map((picture, index) => {
          return <Card key={index} picture={picture} upVote={upVote} downVote={downVote} style={styling(picture.votes)}/>
          })
        }
      </div>
    </div>
  )
}

export default App


Solution 1:[1]

You pass the properties that can update the results of the function in an array, e.g., useMemo(() => { ... }, [propOne, propTwo]) like many other hooks.

In your case you'd pass votes.

Solution 2:[2]

The style prop requires an object. To have it working you have to change:

<Card
  key={index}
  picture={picture}
  upVote={upVote}
  downVote={downVote}
  style={{
    color: styling(picture.votes)
  }}
/>

Or return the object from your function and then use directly as you are already using.

Solution 3:[3]

 //in parent component of App:
 return <Card key={index} picture={picture} upVote={upVote} downVote={downVote} votes={picture.votes}/>

// in your child functional component votes is a prop passed in dynamically, let's memoize it to `styleBaseOnVote` to stop unnecessary re-renders.
   function ChildComponent(picture: <yourPictureObjInterface>, upVote: function, downVote:function, votes: Number): ReactElement {
    const styleBaseOnVote = useMemo(() => {
    let styling = '#696969'

  if (votes > 0) {
    styling = '#008000'
  } else if (votes < 0) {
    styling = '#B22222'
  }

  return styling
    }
, [votes])

   return <div style={{color: styleBaseOnVote}}
}

Solution 4:[4]

useMemo needs to store an object that matches valid CSS properties. Here's an example for setting the width and height of a div.

const MyCustomImage = (props) => {
    const wrapperStyle = useMemo(() => {
        return {width: props.width, height: props.height};
    }, [props.width, props.height]);

    return (
        <div style={wrapperStyle}>
            test
        </div>
    );
};

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dave Newton
Solution 2 Ziru Zanrgeiff
Solution 3 Mark Mu
Solution 4 Ash Blue