I'm doing some testing on my UI and I've noticed that if any state changes in my redux store my ponent (shown below) re-renders and restarts with embedded video at 0. If I type in a redux-connected text field, it remounts, if a status notification hits the store, it remounts, etc.
I have no idea how to fix this and I could really use some help figuring out how to go after the bug.
tldr; How can I stop my VideoPlayer from re-rendering each time something changes in my redux store?
redux-toolkit
react
ponent
const MyComponent = () => {
...
// data used in the VideoPlayer is descructured from this variable:
const formState = useSelector(selectDynamicForm);
// renders output here in the same ponent
return (
...
{sourceContentFound === false ? (
<VideoPlayerDisabled />
) : (
<VideoPlayerController
title={title}
description={description}
sourceAddress={iframeURL}
author={authorName}
timeStamp={{ startTime: 0 }}
/>
)}
)
...
}
formSlice
export const dynamicFormSlice = createSlice({
name: 'dynamicForm',
initialState,
reducers: {
updateField: (state, action) => {
state = action.payload;
return state;
}
},
});
export const selectDynamicForm = createSelector(
(state: RootState): dynamicFormState => state.dynamicForm,
dynamicForm => dynamicForm
);
statusHandlerSlice
I don't think this ponent does anything crazy, per-say, but I have a notification appear when the video conditions are met. When it goes back down clearStatus
the video player restarts.
export const statusHandlerSlice = createSlice({
name: 'statusHandler',
initialState,
reducers: {
setStatus: (state, action: PayloadAction<IStatusObject>) => {
const { type, display, message } = action.payload;
state.status = {
...action.payload,
message: message.charAt(0).toUpperCase() + message.slice(1),
};
if (display === 'internal-only' || display === 'support-both') {
statusLogger(type, message);
}
},
clearStatus: state => {
state.status = {
type: 'success',
data: {},
message: '',
display: 'internal-only',
key: '',
};
},
},
});
export const { setStatus, clearStatus } = statusHandlerSlice.actions;
export const selectStatus = (state: RootState): IStatusObject =>
state.statusHandler.status;
I'm doing some testing on my UI and I've noticed that if any state changes in my redux store my ponent (shown below) re-renders and restarts with embedded video at 0. If I type in a redux-connected text field, it remounts, if a status notification hits the store, it remounts, etc.
I have no idea how to fix this and I could really use some help figuring out how to go after the bug.
tldr; How can I stop my VideoPlayer from re-rendering each time something changes in my redux store?
redux-toolkit
react
ponent
const MyComponent = () => {
...
// data used in the VideoPlayer is descructured from this variable:
const formState = useSelector(selectDynamicForm);
// renders output here in the same ponent
return (
...
{sourceContentFound === false ? (
<VideoPlayerDisabled />
) : (
<VideoPlayerController
title={title}
description={description}
sourceAddress={iframeURL}
author={authorName}
timeStamp={{ startTime: 0 }}
/>
)}
)
...
}
formSlice
export const dynamicFormSlice = createSlice({
name: 'dynamicForm',
initialState,
reducers: {
updateField: (state, action) => {
state = action.payload;
return state;
}
},
});
export const selectDynamicForm = createSelector(
(state: RootState): dynamicFormState => state.dynamicForm,
dynamicForm => dynamicForm
);
statusHandlerSlice
I don't think this ponent does anything crazy, per-say, but I have a notification appear when the video conditions are met. When it goes back down clearStatus
the video player restarts.
export const statusHandlerSlice = createSlice({
name: 'statusHandler',
initialState,
reducers: {
setStatus: (state, action: PayloadAction<IStatusObject>) => {
const { type, display, message } = action.payload;
state.status = {
...action.payload,
message: message.charAt(0).toUpperCase() + message.slice(1),
};
if (display === 'internal-only' || display === 'support-both') {
statusLogger(type, message);
}
},
clearStatus: state => {
state.status = {
type: 'success',
data: {},
message: '',
display: 'internal-only',
key: '',
};
},
},
});
export const { setStatus, clearStatus } = statusHandlerSlice.actions;
export const selectStatus = (state: RootState): IStatusObject =>
state.statusHandler.status;
Share
Improve this question
asked Sep 11, 2021 at 2:45
kevinkevin
3,5566 gold badges39 silver badges78 bronze badges
1
-
If you replace formState and set it with an object:
const formState = {}
will it still re render? Maybe it's props passed from parent that causes the re render. It is not clear why formState is needed since the code in your question never uses it. – HMR Commented Sep 11, 2021 at 7:05
2 Answers
Reset to default 5Your MyComponent
is re-render every time redux store state change is because you have a selector in it
You could stop this to happen by, add an equalityFn to useSelector
.
You can write your own equalityFn
or use some existing function from a library that supports deep parison.
Ex: Use lodash isEqual
import { isEqual } from 'lodash';
const MyComponent = () => {
...
// data used in the VideoPlayer is descructured from this variable:
const formState = useSelector(selectDynamicForm, isEqual);
By default, useSelector
use a shallow
pare which can't detect deep changes inside your object, change to a deep parison function like isEqual
will help you to do that, but It's not remended for all selector since there will be a performance impact.
Live Example:
- I suggest either creating a custom equalFn to pare the data you're using in the current ponent or do not select the whole slice, maybe some properties change is unnecessary for your ponent. like:
const { data } = useSelector(store => store.sliceA, shallowEq);
// console.log(data) => { a: "foo", b: "bar" }
// data.b is useless but once it is changed, the ponent will re-render as well
return <Typography>{data.a}</Typography>
You should install React Devtools, turn on profiler, remember to check
Record why each ponent rendered while profiling
in setting to see what is causing re-rendering. sometimes custom hooks in libraries trigger re-rendering.whyDidYouRender is a good choice too
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745553448a4632684.html
评论列表(0条)