import React, { useState, useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { editZoneMaster } from "../../../redux/actions/GeneralMaster/ZoneMaster";
export default function ModalForm() {
let dispatch = useDispatch();
const [formData, setFormData] = useState({});
const [state, setState] = useState({
open: false
});
const UI = useSelector(state => state.UI);
const handleOpen = () => {
setState({
...state,
open: true
});
};
const handleClose = () => {
setState({
...state,
open: false
});
};
const onChange = e =>
setFormData({ ...formData, [e.target.name]: e.target.value });
const handleSubmit = async e => {
e.preventDefault();
dispatch(editZoneMaster(formData));
console.log(UI.errors)
console.log(Object.keys(UI.errors).length)
if (Object.keys(UI.errors).length === 0) handleClose();
};
控制台输出:
我正在尝试验证我的表单,以防止用户在检测到任何错误时关闭模式。在第一个提交时不会记录错误,仅在第二个提交时会记录。状态已正确更改。而且在返回错误时,它运行良好。但不在渲染上。
答案 0 :(得分:0)
在分派后立即记录状态不会向您显示新状态,因为分派动作是异步的,即,影响状态需要花费时间(通常是很短的时间)。
要跟踪对象中的更改,应使用useEffect
钩子,如下所示:
useEffect(() => {
console.log(UI.errors);
console.log(Object.keys(UI.errors).length);
}, [ UI.errors ]);
(并从handleSubmit中删除console.log调用)
答案 1 :(得分:0)
这是因为UI仅在下一个渲染中会更改。没有魔术绑定,UI值更改在分派后立即反映出来。如果您想在分派后立即获得经过验证的值,则需要使用useStore钩子(https://react-redux.js.org/next/api/hooks#usestore),如下所示:
import React, { useState, useEffect } from "react";
import { useSelector, useDispatch, useStore } from "react-redux";
import { editZoneMaster } from "../../../redux/actions/GeneralMaster/ZoneMaster";
export default function ModalForm() {
let dispatch = useDispatch();
const [formData, setFormData] = useState({});
const [state, setState] = useState({
open: false
});
const UI = useSelector(state => state.UI);
const store = useStore();
const handleOpen = () => {
setState({
...state,
open: true
});
};
const handleClose = () => {
setState({
...state,
open: false
});
};
const onChange = e =>
setFormData({ ...formData, [e.target.name]: e.target.value });
const handleSubmit = async e => {
e.preventDefault();
dispatch(editZoneMaster(formData));
const updatedUI = store.getState().UI; // this is now updated UI state
console.log(updatedUI.errors)
console.log(Object.keys(updatedUI.errors).length)
if (Object.keys(updatedUI.errors).length === 0) handleClose();
};
但是说实话,我更喜欢这种方法(我认为更干净):
import React, { useState, useEffect } from "react";
import { useSelector, useDispatch, useStore } from "react-redux";
import { editZoneMaster } from "../../../redux/actions/GeneralMaster/ZoneMaster";
export default function ModalForm() {
let dispatch = useDispatch();
const [formData, setFormData] = useState({});
const [state, setState] = useState({
open: false
});
const UI = useSelector(state => state.UI);
useEffect(() => {
console.log(UI.errors)
console.log(Object.keys(UI.errors).length)
if (Object.keys(UI.errors).length === 0) handleClose();}, [setState, UI]);
const handleOpen = () => {
setState({
...state,
open: true
});
};
const handleClose = () => {
setState({
...state,
open: false
});
};
const onChange = e =>
setFormData({ ...formData, [e.target.name]: e.target.value });
const handleSubmit = async e => {
e.preventDefault();
dispatch(editZoneMaster(formData));
};
检查验证并在更改后关闭UI的位置。两种解决方案都是有效的。
希望这会有所帮助。