Как оптимизировать перерисовку 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]);
→ Ссылка