更新请求后如何触发useEffect重新渲染

时间:2020-05-30 17:38:24

标签: javascript reactjs react-hooks use-effect use-state

import React, { useState, useEffect } from "react";
import axios from "axios";
import styled from "styled-components";
import Form from "react-bootstrap/Form";
import Col from "react-bootstrap/Col";
import Button from "react-bootstrap/Button";
//import Spinner from "react-bootstrap/Spinner";
import FormLoader from "./FormLoader";


function MainSettings() {
const initialState = {
enableCovertMode: false,
safetyInstructions: "",
selectedVisitorReminder: "",
selectedVisitorReminderMeans: "",
selectedNotificationToHost: "",
selectedNotificationVisitor: "",
selectedCheckOutNotificationToHost: "",
selectedCheckOutNotificationToVisitor: "",
enableGuestModule: false,
enableGuestSmsConfirmation: false,
enableGuestAgreement: false,
enableGuestQrcode: false,
isLoading: true,
};
const [state, setState] = useState(initialState);
const [isLoading, setLoading] = useState(false);

const handleChange = (event) => {
const { name, value } = event.target;
setState({
  ...state,
  [name]: value,
});
};

useEffect(() => {
(async () => {
  const header = {
    headers: {
      "Content-Type": "application/json",
      Authorization:
        "Bearer NgTHTNmqFQpV7PyIzX8BBth3rmm0mArg5TqOIQeJUUH5Oa8DXb7UK4ulwyM88Cd7lBJ1n7DG73efcmc4",
    },
  };
  try {
    const res = await axios.get("/api/tenant/all-settings", header);
    const { code, data } = res.data;
    if (code === 200) {
      setState((state) => ({
        ...state,
        isLoading: false,
        enableCovertMode:
          data.mainSettings.enable_covet_mode === 1 ? true : false,
        safetyInstructions: data.mainSettings.safety_instructions,
        selectedVisitorReminder: `${data.mainSettings.enable_visitor_reminder}`,
        selectedVisitorReminderMeans: `${data.mainSettings.visitor_reminder}`,
        selectedNotificationToHost: `${data.mainSettings.visitor_checkin_notification_to_host}`,
        selectedNotificationVisitor: `${data.mainSettings.visitor_checkin_notification_to_visitor}`,
        selectedCheckOutNotificationToHost: `${data.mainSettings.visitor_checkout_notification_to_host}`,
        selectedCheckOutNotificationToVisitor: `${data.mainSettings.visitor_checkout_notification_to_visitor}`,
        enableGuestModule:
          data.guestSettings.enable_guest_module === 1 ? true : false,
        enableGuestSmsConfirmation:
          data.guestSettings.enable_sms_confirmation === 1 ? true : false,
        enableGuestAgreement:
          data.guestSettings.enable_agreement === 1 ? true : false,
        enableGuestQrcode:
          data.guestSettings.enable_scan_qrcode === 1 ? true : false,
      }));

      window.scroll({
        top: 0,
        left: 0,
        behavior: "smooth",
       });
      }
     } catch (err) {
    console.log(err.response.data);
   }
   })();
  const element = document.querySelector(".container");
  console.log(element);
  element.scrollIntoView({ behavior: "smooth" });
  }, []);

 const handleSubmit = async (event) => {
 event.preventDefault();
 try {
  setLoading(true);
  const formData = {
    mainSettings: {
      enable_multiple_qrcode_scan: 0,
      enable_covet_mode: state.enableCovertMode,
      safety_instructions: state.safetyInstructions,
      emergency_sms: state.setEmergencySms,
      visitor_reminder: state.selectedVisitorReminderMeans,
      enable_visitor_reminder: state.selectedVisitorReminder,
      enable_visitor__record_deletion: state.enableVisitorDeletion,
      visitor_deletion_period: state.visitorDeletionPeriod,
      visitor_checkin_notification_to_host:
        state.selectedNotificationToHost,
      visitor_checkin_notification_to_visitor:
        state.selectedNotificationVisitor,
      visitor_checkout_notification_to_host:
        state.selectedCheckOutNotificationToHost,
      visitor_checkout_notification_to_visitor:
        state.selectedCheckOutNotificationToVisitor,
    },
    guestSettings: {
      enable_guest_module: state.enableGuestModule,
      enable_sms_confirmation: state.enableGuestSmsConfirmation,
      enable_agreement: state.enableGuestAgreement,
      enable_scan_qrcode: state.enableGuestQrcode,
      enable_signature: state.enableGuestSignature,
      enable_phone_number_as_required: state.enableGuestPhoneAsRequired,
      enable_checkin_receipt_printing: state.enableGuestCheckInReceipt,
      enable_checkout_receipt_printing: state.enableGuestCheckOutReceipt,
      qrcode_prefix: state.guestQrcodePrefix,
    },
  };
  const header = {
    headers: {
      "Content-Type": "application/json",
      Authorization:
        "Bearer NgTHTNmqFQpV7PyIzX8BBth3rmm0mArg5TqOIQeJUUH5Oa8DXb7UK4ulwyM88Cd7lBJ1n7DG73efcmc4",
    },
  };
  const response = await axios.put(
    "/api/tenant/all-settings",
    formData,
    header
  );

  const res = response.data;
  setLoading(false);
  if (res.code === 200) {
    console.log("sbmitted", res.message);
  }
} catch (error) {
  console.log(error.response.data);
 }
};

return (
 <div id="formId">
  {state.isLoading ? (
    <FormLoader />
  ) : (
    <Form onSubmit={handleSubmit}>
      <h6 className="mt-4"> Watchlist Settings</h6>
      <hr />
      <br />
      <Form.Row>
        <Form.Group as={Col} md="4">
          <Form.Check
            type="switch"
            id="enableCovertMode"
            label="Enable Convert Mode"
            checked={state.enableCovertMode}
            onChange={() =>
              setState({
                ...state,
                enableCovertMode: !state.enableCovertMode,
              })
            }
          />
        </Form.Group>
      </Form.Row>
      <SubmitBtn>
        <Button type="submit" disabled={isLoading}>
          {/*              {" "}
          {isLoading ? (
           <Spinner animation="border" />
          ) : (
            "Submit Form"
          )} */}
          Submit Form
        </Button>
      </SubmitBtn>
    </Form>
  )}
</div>
);
}

我有一个初始状态,发出HTTP请求后,我用请求中的值更新了初始状态。当用户更新这些值时,我会发出另一个HTTP请求来更新这些值。我有一个useEffect,可从此处获取数据以更新初始状态值。在那个useEffect中,如果添加状态依赖项,则会导致无限循环。由于我的表单字段很多,因此我希望在提交表单后再次运行useEffect,这将触发重新渲染并自动滚动到顶部。由于表格很多,因此我从问题中删除了一些字段。我使用什么依赖项才能使useEffect再次运行并重新渲染以使自动滚动工作。

1 个答案:

答案 0 :(得分:0)

由于您不想更新API,因此不需要运行第一个useEffect。您可以做的是将滚动逻辑带入另一个useEffect

useEffect(() => {
(async () => {
  const header = {
    headers: {
      "Content-Type": "application/json",
      Authorization:
        "Bearer NgTHTNmqFQpV7PyIzX8BBth3rmm0mArg5TqOIQeJUUH5Oa8DXb7UK4ulwyM88Cd7lBJ1n7DG73efcmc4",
    },
  };
  try {
    const res = await axios.get("/api/tenant/all-settings", header);
    const { code, data } = res.data;
    if (code === 200) {
      setState((state) => ({
        ...state,
        isLoading: false,
        enableCovertMode:
          data.mainSettings.enable_covet_mode === 1 ? true : false,
        safetyInstructions: data.mainSettings.safety_instructions,
        selectedVisitorReminder: `${data.mainSettings.enable_visitor_reminder}`,
        selectedVisitorReminderMeans: `${data.mainSettings.visitor_reminder}`,
        selectedNotificationToHost: `${data.mainSettings.visitor_checkin_notification_to_host}`,
        selectedNotificationVisitor: `${data.mainSettings.visitor_checkin_notification_to_visitor}`,
        selectedCheckOutNotificationToHost: `${data.mainSettings.visitor_checkout_notification_to_host}`,
        selectedCheckOutNotificationToVisitor: `${data.mainSettings.visitor_checkout_notification_to_visitor}`,
        enableGuestModule:
          data.guestSettings.enable_guest_module === 1 ? true : false,
        enableGuestSmsConfirmation:
          data.guestSettings.enable_sms_confirmation === 1 ? true : false,
        enableGuestAgreement:
          data.guestSettings.enable_agreement === 1 ? true : false,
        enableGuestQrcode:
          data.guestSettings.enable_scan_qrcode === 1 ? true : false,
      }));

      window.scroll({
        top: 0,
        left: 0,
        behavior: "smooth",
       });
      }
     } catch (err) {
    console.log(err.response.data);
   }
   })();
  }, []);

useEffect(() => {
   if(isLoading === false && state.isLoading === false) {
       const element = document.querySelector(".container"); // use ref instead of document selector
       console.log(element);
       element.scrollIntoView({ behavior: "smooth" });
   }
},[state.isLoading, isLoading]); // allow scroll based on loading state