-
Notifications
You must be signed in to change notification settings - Fork 44
remove UNSAFE component function and clean up state #1851
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
export function saveImageSize(width, height, pixelsPerMm) { | ||
return { type: 'SAVE_IMAGE_SIZE', width, height, pixelsPerMm }; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw that this action was also never called, so removed it. Instead there is an action called setVideoSize
which is used by mxcube, to change the above parameters.
componentDidUpdate(prevProps) { | ||
const { imageRatio, width } = this.props; | ||
if (imageRatio !== prevProps.imageRatio || width !== prevProps.width) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not super happy myself with this solution, as it will trigger 3 re-renders when the video size changes (Which was in fact the initial behaviour). This is somewhat reletad to the fact that imageRatio
prop in this component does not equal imageRatio
from the state, but imageRatio * sourceScale
. I think that there might be a way to improve this, but it would need some more investigation. Here I went with the easier implementation that keeps the previous behaviour but removes the unwanted UNSAFE
function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replacing UNSAFE_componentWillReceiveProps
is a really great first step. 👍
This imageRatio
business rings a bell actually. Seems like the Redux store should maybe hold on to clientWidth
instead of imageRatio
so that the ratio can be recomputed where needed in the component. EDIT: this would in fact get us closer to a modern solution with a useMeasure
hook.
Alternatively, I wonder if just recomputing and setting imageRatio
inside the SAVE_IMAGE_SIZE
case of the reducer would do the trick. 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, the imageRatio
from the state represents the clientWidth
of the outer-wrapper of the SampleImage
. The SampleImage
container calculates scale * clientWidth
and passes this result as imageRatio
(definitely a naming problem 😅 ) prop to SampleImage
.
One have to keep in mind that when the scale resp. the size of the original image changes, the size of the wrapper element will change as well, but since it is rendered within the SampleImage
component the clientwidth will only update after the component mounted, which will then in turn trigger another re-render, since the state for the clientWidth
(i.e. imageRatio
). There will also be a final re-render afterwards, for the check, so that makes 3 renders for a change to the scale value coming from SAVE_IMAGE_SIZE
.
I think, as you mentioned, having something like useMeasure
might be ideal here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imageRatio
is computed to clientWidth / state.width
in the reducer when the SET_IMAGE_RATIO
action is dispatched:
mxcubeweb/ui/src/reducers/sampleview.js
Line 97 in 2050f23
return { ...state, imageRatio: action.clientWidth / state.width }; |
That's the computation that is making a lot of things more complicated than they need to be, I think (and why I'm arguing for storing clientWidth
in the state instead).
But I get your point about having to remeasure the container after changing the image size and after re-rendering SampleImage
. This definitely requires either componentDidUpdate
with a width
check or a ResizeObserver
to be set up on the container (as would useMeasure
do).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fantastic!
componentDidUpdate(prevProps) { | ||
const { imageRatio, width } = this.props; | ||
if (imageRatio !== prevProps.imageRatio || width !== prevProps.width) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replacing UNSAFE_componentWillReceiveProps
is a really great first step. 👍
This imageRatio
business rings a bell actually. Seems like the Redux store should maybe hold on to clientWidth
instead of imageRatio
so that the ratio can be recomputed where needed in the component. EDIT: this would in fact get us closer to a modern solution with a useMeasure
hook.
Alternatively, I wonder if just recomputing and setting imageRatio
inside the SAVE_IMAGE_SIZE
case of the reducer would do the trick. 🤔
daa0282
to
41dc062
Compare
41dc062
to
6f5239b
Compare
6f5239b
to
46bac6c
Compare
This PR removes the
UNSAFE_componentWillRemoveProps
function fromSampleImage
. The function did two things previously:componentDidUpdate
GridPlugin
. This is actually already called every time the component updates (plugin is updated in the render function) and could safely be removed.Furthermore, there were additional checks for
cinema
andautoScale
modes. However, toggle actions existed to change the corresponding states, but were never triggered in the code (they always equaled the initial state value). Since, this was the only place where those state variables were used, I removed them from the state as well as the actions