【发布时间】:2021-01-07 14:57:41
【问题描述】:
我正在制作一个应用程序,但我遇到了一个我不太理解的错误。显然,它是我用来制作受保护页面的钩子。我在下面分享错误和代码。
未处理的运行时错误错误:重新渲染次数过多。 React 限制了 防止无限循环的渲染次数。
import firebase from "firebase";
const firebaseConfig = {
apiKey: "Key",
authDomain: "Domain",
databaseURL: "URL",
projectId: "Id",
storageBucket: "Bucket",
messagingSenderId: "SenderId",
appId: "appId",
measurementId: "measurementId",
};
// Initialize Firebase
!firebase.apps.length && firebase.initializeApp(firebaseConfig);
export const database = firebase.database().ref();
const mapUserFromFirebaseAuthToUser = (user) => {
const { displayName, email, uid } = user;
return {
userName: displayName,
email,
uid,
};
};
export const onAuthStateChanged = (onChange) => {
const emailProvider = new firebase.auth();
return emailProvider.onAuthStateChanged((user) => {
const normalizedUser = user ? mapUserFromFirebaseAuthToUser(user) : null;
onChange(normalizedUser);
});
};
export const loginUser = ({ email, password }) => {
const emailProvider = new firebase.auth();
return emailProvider.signInWithEmailAndPassword(email, password);
};
export const singUp = () => {
const emailProvider = new firebase.auth();
return emailProvider.signOut();
};
应用中断的页面
import { useState, useEffect } from "react";
import styles from "styles/Countries.module.css";
import useUser, { USER_STATES } from "hooks/useUser";
import NavbarMenu from "components/navBar";
import Footer from "components/footer";
import { database } from "utils/firebase";
import {
Table,
Button,
Container,
Modal,
ModalBody,
ModalHeader,
ModalFooter,
FormGroup,
} from "reactstrap";
export default function Countries() {
const user = useUser();
const [timeLine, setTimeLine] = useState([]);
const [isOpenModalAdd, setIsOpenModalAdd] = useState(false);
const [isOpenModalEdit, setIsOpenModalEdit] = useState(false);
const [name, setName] = useState("");
const [currency, setCurrency] = useState("");
const [base, setBase] = useState("");
const [km, setKm] = useState("");
const [minute, setMinute] = useState("");
const [code, setCode] = useState("");
const [country, setCountry] = useState({
name: "",
currency_code: "",
base_fare: "",
per_km: "",
per_minute: "",
});
useEffect(() => {
database.child("Admin/Country").on("value", (snapshot) => {
setTimeLine(snapshot.val());
});
}, []);
const selectCountry = (data, id, status) => {
setCountry(data);
setCode(id);
status === "edit" && setIsOpenModalEdit(true);
};
const editCountry = () => {
database.child("Admin/Country/" + code).set(country);
resetModalAdd();
setIsOpenModalEdit(false);
};
const saveCountry = () => {
const MapCountry = {
name: name,
currency_code: currency,
base_fare: base,
per_km: km,
per_minute: minute,
};
database.child("Admin/Country/" + code).set(MapCountry);
resetModalAdd();
setIsOpenModalAdd(false);
};
const resetModalAdd = () => {
setName("");
setCurrency("");
setBase("");
setKm("");
setMinute("");
setCode("");
};
const openModalAdd = () => {
setIsOpenModalAdd(true);
};
const closeModalAdd = () => {
setIsOpenModalAdd(false);
};
const handleChangeName = (event) => {
const { value } = event.target;
setName(value);
let string = value;
let part = string.split("");
if (part.length === 2) {
let code = part[0].toUpperCase() + part[1].toUpperCase();
setCode(code);
}
};
const handleChangeData = (event) => {
const { value } = event.target;
setCountry(value);
};
const handleChangeCurrency = (event) => {
const { value } = event.target;
setCurrency(value);
};
const handleChangeBase = (event) => {
const { value } = event.target;
setBase(value);
};
const handleChangeKm = (event) => {
const { value } = event.target;
setKm(value);
};
const handleChangeMinute = (event) => {
const { value } = event.target;
setMinute(value);
};
return user ? (
<>
<div className={styles.container}>
<div className={styles.principalMenu}>
<NavbarMenu>
<div className={styles.titleHeader}>
<div className={styles.title}>Administration System</div>
<div className={styles.subtitle}>User: {user.userName}</div>
</div>
</NavbarMenu>
</div>
<div>
<h3>Country</h3>
</div>
<Container>
<Button color="primary" onClick={openModalAdd}>
New Country
</Button>
<Table>
<thead>
<tr>
<th>Name</th>
<th>Currency Code</th>
<th>Base Fare</th>
<th>Per Km</th>
<th>Per Minute</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{Object.keys(timeLine).map((i) => {
return (
<tr key={i}>
<td>{timeLine[i].name}</td>
<td>{timeLine[i].currency_code}</td>
<td>{timeLine[i].base_fare}</td>
<td>{timeLine[i].per_km}</td>
<td>{timeLine[i].per_minute}</td>
<td>
<Button
color="primary"
onClick={selectCountry(timeLine[i], i, "edit")}
>
Editar
</Button>
{" "}
<Button color="danger">Eliminar</Button>
</td>
</tr>
);
})}
</tbody>
</Table>
<Modal isOpen={isOpenModalAdd}>
<ModalHeader>Insertar Registro</ModalHeader>
<ModalBody>
<div className="form-group">
<label>Name: </label>
<br />
<input
type="text"
className="form-control"
value={name}
onChange={handleChangeName}
/>
<label>Currency Code: </label>
<br />
<input
type="text"
className="form-control"
value={currency}
onChange={handleChangeCurrency}
/>
<label>Base Fare: </label>
<br />
<input
type="text"
className="form-control"
value={base}
onChange={handleChangeBase}
/>
<label>Per Km: </label>
<br />
<input
type="text"
className="form-control"
value={km}
onChange={handleChangeKm}
/>
<label>Per Minute: </label>
<br />
<input
type="text"
className="form-control"
value={minute}
onChange={handleChangeMinute}
/>
</div>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={saveCountry}>
Guardar
</Button>
{" "}
<Button color="danger" onClick={closeModalAdd}>
Cancelar
</Button>
</ModalFooter>
</Modal>
<Modal isOpen={isOpenModalEdit}>
<ModalHeader>Editar Registro</ModalHeader>
<ModalBody>
<div className="form-group">
<label>Name: </label>
<br />
<input
type="text"
className="form-control"
name="name"
value={country.name}
onChange={handleChangeData}
/>
<label>Currency Code: </label>
<br />
<input
type="text"
className="form-control"
name="currency_code"
value={country.currency_code}
onChange={handleChangeData}
/>
<label>Base Fare: </label>
<br />
<input
type="text"
className="form-control"
name="base_fare"
value={country.base_fare}
onChange={handleChangeData}
/>
<label>Per Km: </label>
<br />
<input
type="text"
className="form-control"
name="per_km"
value={country.per_km}
onChange={handleChangeData}
/>
<label>Per Minute: </label>
<br />
<input
type="text"
className="form-control"
name="per_minute"
value={country.per_minute}
onChange={handleChangeData}
/>
</div>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={editCountry}>
Guardar
</Button>
{" "}
<Button color="danger" onClick={setIsOpenModalEdit(false)}>
Cancelar
</Button>
</ModalFooter>
</Modal>
</Container>
<Footer />
</div>
</>
) : user === USER_STATES.NOT_KNOWN ? (
<>
<div className={styles.container}>
<h1>Loading...</h1>
</div>
</>
) : (
<>
<div className={styles.container}>
<h1>Not authorized</h1>
</div>
</>
);
}
用于受保护页面的钩子:
import { Router } from "next/router";
import { useState, useEffect } from "react";
import { useRouter } from "next/router";
import { onAuthStateChanged } from "utils/firebase";
export const USER_STATES = {
NOT_LOGGED: null,
NOT_KNOWN: undefined,
};
export default function useUser() {
const [user, setUser] = useState(USER_STATES.NOT_KNOWN);
const router = useRouter();
useEffect(() => {
onAuthStateChanged(setUser);
}, []);
useEffect(() => {
user === USER_STATES.NOT_LOGGED && router.push("/login");
}, [user]);
return user;
}
我希望这足以帮助我。我已经尝试解决,但事实是我没有找到问题。
【问题讨论】:
-
也许还有更多,但
onClick={setIsOpenModalEdit(false)}没有将处理程序设置为某些东西,它会调用该函数。至少你应该onClick={() => setIsOpenModalEdit(false)}