Sometimes UI brings constraints that make development a little bit harder. This week at Entria I need to implement an array of labels that fills buttons.
The problem, simply, I need all buttons to have the same size because of the UI. Reading the React docs I found a simple way to implement this and I think should be a good idea shared with everyone.
So, just to situate us let's imagine that we need to implement a scale of buttons. And the labels of these buttons are dynamic, so the user can have any type of strings on this.
A good scale example can be: "does not meet", "partially meets", "meets", "surpasses".
That is, we have our array ["does not meet", "partially meets", "meets", "surpasses"]
Our component will receive these labels as array from our backend. Thinking our user in some scenarios will have a poor internet connection, we need to understand how to handle this case until we have the bigger text. So, I create a hook for this:
const [isCalculating, setIsCalculating] = useState<boolean>(true);
Until this hook will set as false
, our component won't be rendered. After, we need to calculate the bigger text of all. At this point, we go to this react doc https://reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node.
Based on this, we will measure a DOM node and with our hook, we can know if this is already done or not.
If our hook isCalculating
is true we will call a function to get the biggerText
and set it on a DOM node (span tag).
if (isCalculating) { | |
const biggestText = getBiggerTextWidth(); | |
return <span ref={measuredRef}>{biggestText}</span>; | |
} |
The function's really easy and simple. I just got my array of labels and with a reduce I got the bigger text and return it.
const getBiggerTextWidth = () => { | |
return labels.reduce((acc, cur) => { | |
if (cur.length >= acc.length) { | |
return cur; | |
} | |
return acc; | |
}, ''); | |
}; |
When returned, will be set on span
that contains the react measure function example. I just add two things:
New hooks called
setWidth
setting the dom node width. We will use it later.The hooks
isCalculating
setting as false.
const measuredRef = useCallback(node => { | |
if (node !== null) { | |
setWidth(node.getBoundingClientRect().width); | |
} | |
return setIsCalculating(false); | |
}, []); |
Now, our component will check our hook, see it is false and returned our whole component with the scale of buttons.
So, if we have a case where the scale is bigger than width screen, we can handle easily with css flexbox:
Feel free to contact me to give advice about better ways to implement this or improves my English. My DMs on twitter is always open.
Top comments (0)