【问题标题】:The state does not appear to change immediately状态似乎没有立即改变
【发布时间】:2020-01-27 20:06:47
【问题描述】:
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();
  };

控制台输出:

我正在尝试验证我的表单,以防止用户在检测到任何错误时关闭模式。在第一次提交时没有记录错误,只有在第二次提交时才会记录。状态正在正确更改。此外,在返回错误时,它运行良好。但不在渲染中。

【问题讨论】:

  • 能分享一下redux的代码吗?

标签: reactjs redux react-redux react-hooks


【解决方案1】:

在调度后立即记录状态不会显示新状态,因为调度操作是异步的,即影响状态需要时间(通常是很短的时间)。

要跟踪对象的变化,您应该使用useEffect 挂钩,如下所示:

useEffect(() => {
    console.log(UI.errors);
    console.log(Object.keys(UI.errors).length);
}, [ UI.errors ]);

(并从 handleSubmit 中删除 console.log 调用)

【讨论】:

    【解决方案2】:

    这是因为 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 更改后关闭它。两种解决方案都有效。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-24
      • 2013-07-10
      • 2015-02-10
      相关资源
      最近更新 更多