编辑:在下面显示的代码中,用户从未看到该消息,因为状态已重置。屏幕截图仅是显示我想要显示的消息的示例。
当前状态:成功添加到数据库后,将永远不会显示“设施创建成功”消息。但是,如果我删除了重置代码,则当用户离开页面导航并返回时,该消息仍然存在。根本原因是,成功添加到数据库后,我在Redux中的状态具有“成功”设置。如果我对成功消息进行了重置,则用户将永远不会看到它,因为状态已重置为空对象。
理想状态:用户向数据库添加功能,成功消息通过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;
}
};
答案 0 :(得分:0)
我不认为您在上面复制的 useEffect 中实现清理功能是正确的方法。您遇到的问题是在成功变为真后立即触发重置状态的调度。
我认为您正在寻找的是一种使用 Hooks 使用 componentWillUnmount 的方法,这样当您离开页面并且组件被销毁时,它会触发一个以您想要的方式修改状态的操作。
useEffect 上的 return 语句就是这样做的。当组件卸载时,您在 return 语句中包含的任何内容都会被触发。
useEffect(() => {
dispatch(//action to add facility);
return () => {
dispatch(//action to modify state when component unmounts);
};
}, [dispatch]);
使用上述方法,当您导航回页面时,成功将再次为假。
希望这会有所帮助。