更改路线后,React / Redux重置状态

时间:2020-11-05 14:53:09

标签: javascript node.js reactjs redux

编辑:在下面显示的代码中,用户从未看到该消息,因为状态已重置。屏幕截图仅是显示我想要显示的消息的示例。

当前状态:成功添加到数据库后,将永远不会显示“设施创建成功”消息。但是,如果我删除了重置代码,则当用户离开页面导航并返回时,该消息仍然存在。根本原因是,成功添加到数据库后,我在Redux中的状态具有“成功”设置。如果我对成功消息进行了重置,则用户将永远不会看到它,因为状态已重置为空对象。enter image description here

理想状态:用户向数据库添加功能,成功消息通过Redux状态返回,并显示消息。页面刷新,显示新添加的功能。用户离开页面,然后重新设置Redux状态。

除了在useEffect中使用清除功能无济于事外,我还尝试过React的库来检测卸载。

我将在下面列出我的代码,并感谢您的任何反馈或见解。请注意,为了节省空间,一些不相关的代码已被修剪。

FacilityAdminScreen.js(组件)

import React, { useState, useEffect } from "react";
import { Form, Row, Button, Col } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import Message from "../components/Message";
import Loader from "../components/Loader";
import { chunk } from "lodash";
import FacilityCard from "../components/FacilityCard";
import { createFacility, getFacilityAllBasicInfo } from "../actions/facilityActions";
import { FACILITY_ADD_TO_DATABASE_RESET } from "../constants/facilityConstants";

const FacilityAdminScreen = ({ match }) => {
    // State for form information
    const [name, setName] = useState("");
    const [streetAddress1, setStreetAddress1] = useState("");
    const [streetAddress2, setStreetAddress2] = useState("");
    const [city, setCity] = useState("");
    const [state, setState] = useState("");
    const [zip, setZip] = useState("");

    const dispatch = useDispatch();

    // List of facilities for populating page
    const facilityAllBasicInfo = useSelector(state => state.facilityAllBasicInfo);
    const { loading, error } = facilityAllBasicInfo;
    const facilities = chunk(facilityAllBasicInfo.facilities, 2);

    // Response upon adding facility to database
    const facilityAddToDatabase = useSelector(state => state.facilityAddToDatabase);
    const {
        loading: loadingCreate,
        error: errorCreate,
        success: successCreate,
    } = facilityAddToDatabase;

    const submitHandler = e => {
        e.preventDefault();
        // Attempt to create the facility
        dispatch(
            createFacility({
                company: match.params.companyId,
                name,
                streetAddress1,
                streetAddress2,
                city,
                state,
                zip,
            })
        );
    };

    useEffect(() => {
        // Get all facilities for company
        dispatch(getFacilityAllBasicInfo(match.params.companyId));
        // If facility created successfully, reset all form state
        if (successCreate) {
            dispatch({ type: FACILITY_ADD_TO_DATABASE_RESET });
            setName("");
            setStreetAddress1("");
            setStreetAddress2("");
            setCity("");
            setState("");
            setZip("");
        }
    }, [dispatch, successCreate, match.params.companyId]);

    return (
        <>
            <Row>
                <Col md={8}>
                    <h1>Facilities</h1>
                    <h6>Click facility name for detailed information</h6>
                    {loading ? (
                        <Loader />
                    ) : error ? (
                        <Message variant="danger">{error}</Message>
                    ) : (
                        <>
                            {facilities.map((facilityArray, i) => (
                                <Row className="mb-3" key={i}>
                                    {facilityArray.map((facility, i) => (
                                        <Col md={6} key={i}>
                                            <FacilityCard
                                                key={facility._id}
                                                companyId={match.params.companyId}
                                                id={facility._id}
                                                name={facility.name}
                                                streetAddress1={facility.streetAddress1}
                                                streetAddress2={facility.streetAddress2}
                                                city={facility.city}
                                                state={facility.state}
                                                zip={facility.zip}
                                                isActive={facility.isActive}
                                            />
                                        </Col>
                                    ))}
                                </Row>
                            ))}
                        </>
                    )}
                </Col>
                <Col md={4}>
                    <h1>Add Facility</h1>
                    {loadingCreate && <Loader />}
                    {errorCreate && <Message variant="danger">{errorCreate}</Message>}
                    {successCreate && (
                        <Message variant="success">Facility created successfully</Message>
                    )}
                    <Form onSubmit={submitHandler}>
                        {/*Trimmed code here for the sake of space */}
                    </Form>
                </Col>
            </Row>
        </>
    );
};

export default FacilityAdminScreen;

两个减速器都获得设施列表并添加到数据库中:

export const facilityAllBasicInfoReducer = (state = { facilities: [] }, action) => {
    switch (action.type) {
        case FACILITY_ALL_BASIC_INFO_REQUEST:
            return { loading: true };
        case FACILITY_ALL_BASIC_INFO_SUCCESS:
            return { loading: false, facilities: action.payload };
        case FACILITY_ALL_BASIC_INFO_FAIL:
            return { loading: false, error: action.payload };
        default:
            return state;
    }
};

export const facilityAddToDatabaseReducer = (state = {}, action) => {
    switch (action.type) {
        case FACILITY_ADD_TO_DATABASE_REQUEST:
            return { loading: true };
        case FACILITY_ADD_TO_DATABASE_SUCCESS:
            return { loading: false, success: true, facility: action.payload };
        case FACILITY_ADD_TO_DATABASE_FAIL:
            return { loading: false, error: action.payload };
        case FACILITY_ADD_TO_DATABASE_RESET:
            return {};
        default:
            return state;
    }
};

1 个答案:

答案 0 :(得分:0)

我不认为您在上面复制的 useEffect 中实现清理功能是正确的方法。您遇到的问题是在成功变为真后立即触发重置状态的调度。

我认为您正在寻找的是一种使用 Hooks 使用 componentWillUnmount 的方法,这样当您离开页面并且组件被销毁时,它会触发一个以您想要的方式修改状态的操作。

useEffect 上的 return 语句就是这样做的。当组件卸载时,您在 return 语句中包含的任何内容都会被触发。

    useEffect(() => {
        dispatch(//action to add facility);
        return () => {
            dispatch(//action to modify state when component unmounts);
        };
    }, [dispatch]); 

使用上述方法,当您导航回页面时,成功将再次为假。

希望这会有所帮助。