Javascript React应用程序';减速';当我尝试在firebase.auth()内分派操作时。onAuthStateChanged()方法
我正在尝试在我的React应用程序中实现Firebase身份验证。 我有登录和注销按钮,它们工作正常(我可以使用console.log uid) 重定向也可以。 然后我尝试添加新的reducer'user':{uid:uid}或'user':{}(如果注销)。 此时,我的应用程序不想运行,浏览器显示通知“网页正在减慢浏览器速度” 那是GitHub App.js:Javascript React应用程序';减速';当我尝试在firebase.auth()内分派操作时。onAuthStateChanged()方法,javascript,reactjs,firebase,redux,Javascript,Reactjs,Firebase,Redux,我正在尝试在我的React应用程序中实现Firebase身份验证。 我有登录和注销按钮,它们工作正常(我可以使用console.log uid) 重定向也可以。 然后我尝试添加新的reducer'user':{uid:uid}或'user':{}(如果注销)。 此时,我的应用程序不想运行,浏览器显示通知“网页正在减慢浏览器速度” 那是GitHub App.js: import ReactDOM from "react-dom"; import Navigation from "../router
import ReactDOM from "react-dom";
import Navigation from "../routers/Navigation";
import { firebase, database } from "../firebase/firebase";
import { startSetExpenses, setFiltersText } from "../redux/actions";
import { createBrowserHistory } from "history";
import { connect } from "react-redux";
import {logIn, logOut} from '../redux/actions'
let history = createBrowserHistory();
export function App(props) {
firebase.auth().onAuthStateChanged((user) => {
if (!user) {
props.dispatch(logOut())
history.push("/");
} else {
props.dispatch(logIn(user.uid))
if (history.location.pathname === "/") {
history.push("/dashboard");
}
}
});
return (
<div>
<h1>Expenses App</h1>
<Navigation history={history}/>
</div>
);
}
let mapStoreToProps = (dispatch) => {
return {
dispatch
}
}
export default connect(mapStoreToProps)(App)
你检查控制台了吗?我会检查登录(…)操作是否被多次调用。我认为问题在于firebase.auth().onAuthStateChanged()是InCode应用程序组件。当它改变状态时,会产生无限循环,但我不知道为什么。顺便说一句,我从index.js文件中的组件中删除了它,现在它可以工作了。但是代码看起来真的很糟糕。嗨!您可以尝试将
firebase.auth().onAuthStateChanged()
放在useffect
钩子中,该钩子仅在组件挂载时运行,例如功能组件中的componentDidMount
。这使得监听器只在组件挂载时设置一次,而不是每次组件呈现时设置一次。您检查控制台了吗?我会检查登录(…)操作是否被多次调用。我认为问题在于firebase.auth().onAuthStateChanged()是InCode应用程序组件。当它改变状态时,会产生无限循环,但我不知道为什么。顺便说一句,我从index.js文件中的组件中删除了它,现在它可以工作了。但是代码看起来真的很糟糕。嗨!您可以尝试将firebase.auth().onAuthStateChanged()
放在useffect
钩子中,该钩子仅在组件挂载时运行,例如功能组件中的componentDidMount
。这使得监听器仅在组件装载时设置一次,而不是每次组件渲染时设置一次。
const initialState = {
filters: {
text: ""
},
expenses: [],
user: {}
};
function userReducer(state = {}, action) {
const {type, uid} = action
switch (type) {
case "LOGIN":
return {
uid: uid
}
case "LOGOUT":
return {}
default :
return state;
}
}
function expensesReducer(state = initialState.expenses, action) {
const { type,id, description, value, updates,expenses } = action;
switch (type) {
case "ADD_EXPENSE":
return [
...state,
{
id,
description,
value,
},
];
case "REMOVE_EXPENSE":
if (state.findIndex(expense => expense.id === id) < 0) throw new Error('index is not found')
return state.filter((expense) => expense.id !== id);
case "UPDATE_EXPENSE":
return state.map((expense) => {
return expense.id === id ? { ...expense, ...updates } : expense;
});
case "SET_EXPENSES":
if (expenses) {
return expenses
}
default:
return state;
}
}
function filtersReducer(state = initialState.filters, action) {
const {type, text} = action;
switch (type) {
case 'SET_FILTERS_TEXT':
return {...state, text}
default:
return state;
}
}
const rootReducer = combineReducers({
filters: filtersReducer,
expenses: expensesReducer,
user: userReducer
})
export default rootReducer
import {database, firebase, googleProvider} from "../firebase/firebase";
export function logIn(uid) {
return (dispatch) => {
console.log('uid inside actionCreator', uid)
dispatch({
type: "LOGIN",
uid: uid
})
}
}
export function logOut() {
return (dispatch) => {
console.log('logged out')
dispatch({type: 'LOGOUT'})
}
}
export function startLogIn() {
return () => {
return firebase.auth().signInWithPopup(googleProvider)
}
}
export function startLogOut() {
return () => {
return firebase.auth().signOut()
}
}
export function addExpense({ id, description, value } = {}) {
return {
type: "ADD_EXPENSE",
id,
description,
value,
};
}
export const startAddExpense = (expense) => {
return (dispatch) => {
let newId = database.ref("expenses").push().key;
const { description, value } = expense;
return database
.ref("expenses/" + newId)
.set({ description, value })
.then(() => {
dispatch(
addExpense({
type: "ADD_EXPENSE",
id: newId,
description,
value,
})
);
});
};
};
export function removeExpense(id) {
return {
type: "REMOVE_EXPENSE",
id,
};
}
export const startRemoveExpense = (id) => {
return (dispatch) => {
return database
.ref("expenses/" + id)
.remove()
.then(() => {
console.log("removing expense with id : " + id);
dispatch(removeExpense(id));
})
.catch((error) => {
console.log(`Expense with id:${id} was not removed`);
console.log(error)
});
};
};
export function updateExpense(id, updates) {
return {
type: "UPDATE_EXPENSE",
id,
updates,
};
}
export const startUpdateExpense = (id, updates) => {
return (dispatch) => {
return database.ref('expenses/' + id)
.update(updates)
.then(() => {
dispatch(updateExpense(id, updates))
})
.catch((err) => {
console.log('Error with updating an expense from firebase')
console.log(err)
})
}
}
export function setFiltersText(text) {
return {
type: "SET_FILTERS_TEXT",
text,
};
}
export const setExpenses = (expenses) => {
return {
type: "SET_EXPENSES",
expenses: [...expenses],
};
};
export const startSetExpenses = () => {
return (dispatch) => {
//get expenses from database
//.then dispatch expenses to state with setExpenses
return database
.ref("expenses")
.once("value")
.then((snapshot) => {
const expensesObj = snapshot.val();
let expenses = [];
for (let property in expensesObj) {
expenses = [
...expenses,
{
id: property,
description: expensesObj[property].description,
value: expensesObj[property].value,
},
];
}
dispatch(setExpenses(expenses));
});
};
};