'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 |
