Два запроса на сервер redux
У меня есть необходимость сделать последовательно два запроса на сервер:
getAllPersons и затем getPersonsForSelect.
Данные запросы должны уходить на сервер при загрузке приложения и я делаю их используя useEffect:
useEffect(() => {
dispatch(getAllPersons(mainPersonId))
dispatch(getPersonsForSelect(processName))
},[])
const allbossPerson = useSelector(store => { return store.persons.allbossPerson })
const personsForSelect = useSelector(store => { return store.persons.personsForSelect })
Проблема в том, что используя console.log() я получаю по два обращения на сервер, т.е. всего 4:
import {
GET_ALL_PERSONS,
GET_PERSONS_FOR_SELECT
} from "../types/person"
const initialState = {
allbossPerson: [],
personsForSelect: []
}
export const persons = (state = initialState, action) => {
switch (action.type) {
case GET_ALL_PERSONS:
console.log('GET_ALL_PERSONS')
const allPersons = action.allPersons.slice();
return {
...state,
allbossPerson: allPersons
}
case GET_PERSONS_FOR_SELECT:
console.log('GET_PERSONS_FOR_SELECT')
const personsForSelect = action.personsForSelect.slice();
return {
...state,
personsForSelect: personsForSelect
}
default:
return state
}
}
Т.е. в консоли у меня вот такая картина:
GET_PERSONS_FOR_SELECT
2personReducer.js:14 GET_ALL_PERSONS
personReducer.js:21 GET_PERSONS_FOR_SELECT
Что я делаю не так? Почему вызоываются они по 2 раза?
Ответы (1 шт):
Двойной рендер компонента - стандартное явление для React. Это связано с тем, что при разработке это может помочь найти некоторые ошибки. В данный момент ваш код работает по такой схеме:
Отрисовать компонент -> сделать 2 запроса -> повторно отрисовать компонент -> повторно сделать 2 запроса
Такое поведение явно не играет нам на руку, так что есть несколько способов его избежать.
1 способ - отключить строгий режим. Для этого, нужно открыть файл index.js, который выглядит примерно так (у вас может отличаться, я взял из своего проекта):
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './redux/reducers/rootReducer';
const app = <Provider store={store}>
<BrowserRouter>
<React.StrictMode> // строгий режим
<App />
</React.StrictMode>
</BrowserRouter>
</Provider>
ReactDOM.render(
app, document.getElementById('root')
);
reportWebVitals();
Все, что нужно сделать - закомментировать строчки <React.StrictMode> (или вообще их удалить), после чего строгий режим будет отключен. То есть, файл должен выглядеть так:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './redux/reducers/rootReducer';
const app = <Provider store={store}>
<BrowserRouter>
{/* <React.StrictMode> */}
<App />
{/* </React.StrictMode> */}
</BrowserRouter>
</Provider>
ReactDOM.render(
app, document.getElementById('root')
);
reportWebVitals();
Другой вариант, который не совсем решит проблему, но позволит убедиться, что все работает корректно - забилдить проект. Билд - финальная сборка проекта, то есть это даст вам возможность посмотреть на проект в том виде, в котором он будет размещен в интернете. Для этого, остановите localhost, а затем запустите снова командой npm run build или yarn build. Когда мы билдим проект, строгий режим отключается автоматически, что дает нам возможность увидеть, какое количество рендеров было произведено