Состояние не меняется сразу - PullRequest
0 голосов
/ 27 января 2020
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();
  };

Вывод на консоль:

Output from my console

Я пытаюсь проверить свою форму, чтобы пользователь не мог закрыть модальное окно, если возникли какие-либо ошибки. обнаружено. При первой отправке ошибки не регистрируются, а только при второй отправке. Состояние меняется правильно. Также при возврате ошибок он работает хорошо. Но не на рендере.

Ответы [ 2 ]

0 голосов
/ 27 января 2020

Это потому, что интерфейс будет меняться только при следующем рендере. Не существует привязки magi c, в которой изменения значения пользовательского интерфейса отражаются сразу после отправки. Если вы хотите получить проверенное значение сразу после отправки, вам нужно использовать ловушку 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));
  };

Где вы проверяете проверку и закрываете интерфейс после его изменения. Оба решения верны.

Надеюсь, это поможет.

0 голосов
/ 27 января 2020

Регистрация состояния сразу после отправки не покажет вам новое состояние, поскольку действия по отправке асинхронны, т. Е. Требуется время, чтобы повлиять на состояние (как правило, за короткое время).

Для отслеживания изменений в ваш объект, вы должны использовать хук useEffect, например:

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

(и удалить вызовы console.log из handleSubmit)

...