为什么这个错误:太多重新渲染。 React 限制渲染次数以防止无限循环

时间:2021-02-27 15:33:49

标签: reactjs react-hooks context-api react-lifecycle

任何人都可以帮助我解决这个问题,因为它无法正常工作,也许上下文 API 可能会出现问题我是新手,请帮助我认为我的生命周期钩子中缺少某些东西,我尝试使用组件将安装代替useEffect 但仍然不起作用?也许我遗漏了一些很小的东西,请帮我写代码。 [

import React, {
    useRef,
    useState,
    setState,
    useContext,
    useEffect,
    Fragment,
} from "react";
import Modal from "../components/Modal/Modal";
import Backdrop from "../components/Backdrop/Backdrop";
import EventList from "../components/Events/EventList/EventList";
import Spinner from "../components/Spinner/Spinner";
import AuthContext from "../context/AuthContext";
import "./Events.css";

const EventsPage = () => {
    const [creating, setCreating] = useState(false);
    const [events, setEvents] = useState([]);
    const [isLoading, setIsLoading] = useState(false);
    const [selectedEvent, setSelectedEvent] = useState(null);

    var isActive = true;

    const context = useContext(AuthContext);

    const { titleElRef, priceElRef, dateElRef, descriptionElRef } = useRef(null);

    //componentDidMount and componentWillUnmount equivalent
    useEffect(() => {
        fetchEvents();
        return () => {
            isActive = false;
        };
    }, []);

    const modalConfirmHandler = () => {
        setCreating(false);

        const title = titleElRef.current.value;
        const price = +priceElRef.current.value;
        const date = dateElRef.current.value;
        const description = descriptionElRef.current.value;

        if (
            title.trim().length === 0 ||
            price <= 0 ||
            date.trim().length === 0 ||
            description.trim().length === 0
        ) {
            return;
        }

        const event = { title, price, date, description };
        console.log(event);

        const requestBody = {
            query: `
          mutation CreateEvent($title: String!, $desc: String!, $price: Float!, $date: String!) {
            createEvent(eventInput: {title: $title, description: $desc, price: $price, date: $date}) {
              _id
              title
              description
              date
              price
            }
          }
        `,
            variables: {
                title: title,
                desc: description,
                price: price,
                date: date,
            },
        };

        const token = context.token;

        fetch("http://localhost:5000/graphql", {
            method: "POST",
            body: JSON.stringify(requestBody),
            headers: {
                "Content-Type": "application/json",
                Authorization: "Bearer " + token,
            },
        })
            .then((res) => {
                if (res.status !== 200 && res.status !== 201) {
                    throw new Error("Failed!");
                }
                return res.json();
            })
            .then((resData) => {
                setState((prevState) => {
                    const updatedEvents = [...prevState.events];
                    updatedEvents.push({
                        _id: resData.data.createEvent._id,
                        title: resData.data.createEvent.title,
                        description: resData.data.createEvent.description,
                        date: resData.data.createEvent.date,
                        price: resData.data.createEvent.price,
                        creator: {
                            _id: context.userId,
                        },
                    });
                    return { events: updatedEvents };
                });
            })
            .catch((err) => {
                console.log(err);
            });
    };

    const modalCancelHandler = () => {
        setCreating(false);
        setSelectedEvent(null);
    };

    const fetchEvents = () => {
        setIsLoading(true);
        const requestBody = {
            query: `
          query {
            events {
              _id
              title
              description
              date
              price
              creator {
                _id
                email
              }
            }
          }
        `,
        };

        fetch("http://localhost:5000/graphql", {
            method: "POST",
            body: JSON.stringify(requestBody),
            headers: {
                "Content-Type": "application/json",
            },
        })
            .then((res) => {
                if (res.status !== 200 && res.status !== 201) {
                    throw new Error("Failed!");
                }
                return res.json();
            })
            .then((resData) => {
                const events = resData.data.events;
                if (isActive) {
                    setEvents(events);
                    setIsLoading(false);
                }
            })
            .catch((err) => {
                console.log(err);
                if (isActive) {
                    setIsLoading(false);
                }
            });
    };

    const showDetailHandler = (eventId) => {
        setState((prevState) => {
            const selectedEvent = prevState.events.find((e) => e._id === eventId);
            return { selectedEvent: selectedEvent };
        });
    };

    return (
        <Fragment>
            {(creating || selectedEvent) && <Backdrop />}
            {creating && (
                <Modal
                    title="Add Event"
                    canCancel
                    canConfirm
                    onCancel={modalCancelHandler}
                    onConfirm={modalConfirmHandler}
                    confirmText="Confirm"
                >
                    <form>
                        <div className="form-control">
                            <label htmlFor="title">Title</label>
                            <input type="text" id="title" ref={titleElRef} />
                        </div>
                        <div className="form-control">
                            <label htmlFor="price">Price</label>
                            <input type="number" id="price" ref={priceElRef} />
                        </div>
                        <div className="form-control">
                            <label htmlFor="date">Date</label>
                            <input type="datetime-local" id="date" ref={dateElRef} />
                        </div>
                        <div className="form-control">
                            <label htmlFor="description">Description</label>
                            <textarea id="description" rows="4" ref={descriptionElRef} />
                        </div>
                    </form>
                </Modal>
            )}
            {selectedEvent && (
                <Modal
                    title={selectedEvent.title}
                    canCancel
                    canConfirm
                    onCancel={modalCancelHandler}
                    onConfirm={bookEventHandler}
                    confirmText={context.token ? "Book" : "Confirm"}
                >
                    <h1>{selectedEvent.title}</h1>
                    <h2>
                        ${selectedEvent.price} -{" "}
                        {new Date(selectedEvent.date).toLocaleDateString()}
                    </h2>
                    <p>{selectedEvent.description}</p>
                </Modal>
            )}
            {context.token && (
                <div className="events-control">
                    <p>Share your own Events!</p>
                    <button className="btn" onClick={setCreating(true)}>
                        Create Event
                    </button>
                </div>
            )}
            {isLoading ? (
                <Spinner />
            ) : (
                <EventList
                    events={events}
                    authUserId={context.userId}
                    onViewDetail={showDetailHandler}
                />
            )}
        </Fragment>
    );
};

export default EventsPage;

]1

0 个答案:

没有答案