Я пытаюсь подключиться к своей БД с помощью async / await. При использовании приведенного ниже кода функция handleConnectToDB
, похоже, никогда не вызывается, создает белый экран, на котором приложение в целом никогда не отображает, или выдает ошибку бесконечной визуализации React. В идеале я хочу, чтобы этот обработчик запускался каждый раз, когда пользователь переходит на страницу или обновляет ее, однако я хочу, чтобы он запускался только один раз, а не при повторном рендеринге.
Вызов handleConnectToDB()
автономный : Ошибка бесконечного рендеринга
Вызов React.useEffect(handleConnectToDB());
: Ошибка бесконечного рендеринга
Вызов React.useEffect(handleConnectToDB);
: Приложение никогда не отображает (белый экран)
Вызов React.useEffect(() => handleConnectToDB);
: Отображает приложение + компонент. Обработчик никогда не звонил.
Вызов React.useEffect(() => handleConnectToDB());
: Приложение никогда не отображает (белый экран)
Вызов React.useEffect(() => {handleConnectToDB()}, []);
: Отображает приложение + компонент. Обработчик никогда не вызывается.
Вызов React.useEffect(() => {handleConnectToDB()}, [handleConnectToDB]);
: Отрисовка приложения + компонента. Обработчик никогда не вызывается.
Я добавил несколько операторов console.log()
, чтобы проверить, вызывается ли когда-либо обработчик, и ни один из них не напечатал ни на одном из вышеперечисленных . Я полагаю, что ошибка находится где-то в функции обработчика, поскольку все итерации React.useEffect()
создают некоторую версию ошибки. Я просто не могу понять, что может вызвать бесконечную ошибку. Я также предполагаю, что где-то совершил очень глупую ошибку, которую не могу найти.
Обновление 1 : ошибка бесконечного рендеринга возникает при вызове dispatchSignUpState({
type: 'DB_CONNECT_INIT', payload: ''})
. Я не понимаю, почему это вызывает повторную визуализацию приложения, когда состояние является локальным для компонента.
const SignUpReducer = (state, action) => {
switch (action.type) {
case 'DB_CONNECT_INIT':
return {
...state,
isDBConnecting: true,
isDBConnected: false,
isDBError: false,
querySelectors: action.payload
};
case 'DB_CONNECT_SUCCESS':
return {
...state,
isDBConnecting: false,
isDBConnected: true,
isError: false
};
case 'DB_CONNECT_FAILURE':
return {
...state,
isDBConnecting: false,
isDBConnected: false,
isDBError: true,
errorMessage: action.payload
}
default:
throw new Error();
}
};
const SignUpPage = () => {
//SET UP STATE REDUCER
const [signUpState, dispatchSignUpState] = React.useReducer(
SignUpReducer,
{
querySelectors: [],
errorMessage: '',
isDBConnecting: false,
isDBConnected: false,
isDBError: false
}
);
//connect to the database
const handleConnectToDB = React.useCallback(async () => {
console.log("Debug: handleConnectToDB called.");
dispatchSignUpState({
type: 'DB_CONNECT_INIT',
payload: '',
});
console.log('Beginning connection attempt...');
try {
console.log("Attempting to connect to DB...");
await mongoose.connect( //await connection to mongoDB
'<MYMONGOURI>',
{useNewUrlParser: true}
);
const db = mongoose.connection;
db.once('open', () => {
dispatchSignUpState({type: 'DB_CONNECT_SUCCESS'}); //change SignUpState: DB connection was sucessful.
})
} catch {
dispatchSignUpState({
type: 'DB_CONNECT_FAILURE',
payload: 'Unable to connect to the server.',
});
}
}, []
);
React.useEffect(() => {
handleConnectToDB()}, [handleConnectToDB]);