Как оптимизировать перерисовку react компонентов?
У меня есть компонента страницы Events внутри которой лежит компонента EventFilter.При первой загрузке каждая их них перерисовывается 6 раз. Если закомментировать EventFilter, то компонента Events перерисовывается 2 раза. Внутри EventFilter есть dispatch, если его закомментировать, то оба компонента перерисовываются 2 раза. Как я понимаю проблема в dispatch. Как можно это оптимизировать?
export const Events: React.FC = ()=>{
console.log('events')
const eventsData: EventDataType[] = useSelector<RootState, EventDataType[]>(state=>state.events.events);
const view: number = useSelector<RootState, number>(state=>state.filter.view);
const show: number = useSelector<RootState, number>(state=>state.filter.show);
const start: number = useSelector<RootState, number>(state=>state.filter.start);
return (
<main className='events'>
<div className="container">
<div className="events_wrapper">
<div className='events__header'>
<p>Our Events</p>
<h1>Lectures, workshops & master-classes</h1>
<EventFilter/> // компонента из-за которой перерисовывается Events
</div>
..........
)}
А вот EventFilter внутри которой есть dispatch
export const EventFilter: React.FC = ()=>{
const inputRef = useRef<HTMLInputElement>(null);
const showRef = useRef<HTMLInputElement>(null);
const sortRef = useRef<HTMLSelectElement>(null);
const inputText = useSelector<RootState, string>(state=>state.filter.inputText);
const show = useSelector<RootState, number>(state=>state.filter.show);
const sortby = useSelector<RootState, string>(state=>state.filter.sortby);
const dispatch = useAppDispatch();
React.useEffect(()=>{
dispatch(getEvents(`http://localhost:8000/events/?_sort=day&_order=${sortby}&q=${inputText}`));
}, [inputText, show, sortby, dispatch]);
//console.log('event filter')
return (
<div className="event-filter">
<label htmlFor="themes">
Event category
<select name="themes" id="themes">
<option value="all themes">all themes</option>
</select>
</label>
<label htmlFor="sortby">
Sort by
<select ref={sortRef} onChange={()=>dispatch(setSortby(String(sortRef.current?.value)))} name="sortby" id="sortby">
<option value="newest">newest</option>
<option value="oldest">oldest</option>
</select>
</label>
<label htmlFor="show">
Show
<input type="number" ref={showRef} id="show" step={1} onChange={()=>dispatch(setShow(Number(showRef.current?.value)))} value={`${show}`}/>
</label>
<label htmlFor="page">
events per page
<input ref={inputRef} type="text" id="page" onChange={()=>dispatch(setInputText(String(inputRef.current?.value)))} placeholder='Search event...' />
</label>
<div className="events__view">
<div className="view-1" onClick={()=>dispatch(setView(1))}>
<div></div>
<div></div>
</div>
<div className="view-2" onClick={()=>dispatch(setView(2))}>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
</div>
)
}
Ответы (1 шт):
Автор решения: Ahmed_08
→ Ссылка
StrictMode монтирует компоненту два раза, поэтому компоненты рендерятся больше. Вот измененный код
React.useEffect(()=>{
const abortController = new AbortController();
const signal = abortController.signal;
const params = {
url: `http://localhost:8000/events/?_sort=day&_order=${sortby}&q=${inputText}`,
signal: signal
};
dispatch(getEvents(params));
return ()=> {
abortController.abort('abort')
}
}, [inputText, show, sortby, dispatch]);