繁体   English   中英

React 组件未正确重新加载 stateChange

[英]React Component not correctly reloading on stateChange

我正在使用反应钩子,我有一个子组件Addmember和一个父组件MemberList 在成员列表中,用户单击添加成员并弹出一个模型(子组件),然后用户可以输入一些表单数据然后提交表单。 然后表单将新成员添加到 MongoDB 集合。 parentCallback(true) .then()它调用parentCallback(true)loading的父状态翻转为true ,然后触发组件重新渲染。 这是成功的工作。

这里我无法解决这个问题的问题是,当父级在访问数据库以getMembers时重新呈现时,它没有返回新添加的成员。 如果我刷新页面,相同的调用将成功获取所有成员,包括最近添加的成员。

会员列表.js:

import React, { useState, useEffect } from "react";
import Spinner from "react-bootstrap/Spinner";
import { toast } from "react-toastify";

import { css } from "glamor";
import "react-toastify/dist/ReactToastify.css";
import "react-datepicker/dist/react-datepicker.css";
import "../Styles/ReactDatePicker.css";

import Member from "./Member";

import AddMemberModal from "../models/AddMember";
import RemoveMemberModel from "../models/RemoveMember";

const { getFamily, getMembers } = require("../Utils/Service");

const MemberList = () => {
  const [family, setFamily] = useState({});
  const [familyMembersList, setFamilyMembersList] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    if (loading) {
      fetchData();
    }
  }, [loading]);

  async function fetchData() {
    getFamily.then(result => {
      console.log('get family');
      setFamily(result);
    });

    getMembers.then(result => {
      try {
        console.log('set family list');
        console.log(result);
        setFamilyMembersList(
          result.map((child, index) => (
            <Member
              key={index}
              index={child._id}
              balance={child.balance}
              firstName={child.firstName}
              lastName={child.lastName}
              birthday={child.birthday}
              role={child.role[0]}
            />
          ))
        );
      } catch (e) {
        toast.error("500: Error with Service Call", {
          position: "top-right",
          autoClose: 5000,
          hideProgressBar: false,
          closeOnClick: true,
          pauseOnHover: true,
          draggable: true,
          className: css({
            background: "#ed5565 !important"
          })
        });
      } finally {
        setLoading(false);
      }
    });
  }

  function handleCallback() {
    setLoading(true);
  }

  return (
    <div className="ibox">
      <div className="ibox-title">
        <h5>{family.name}</h5>
        <div className="ibox-tools">
          <span className="label label-warning-light float-right">
            {familyMembersList.length} Member(s)
          </span>
        </div>
      </div>
      <div className="ibox-content">
        <div className="feed-activity-list">
          {loading ? (
            <Spinner animation="grow" role="status" variant="dark">
              <span className="sr-only">Loading...</span>
            </Spinner>
          ) : (
            familyMembersList
          )}
        </div>
        <div className="d-flex">
          <a
            className="btn btn-primary text-white m-t"
            data-toggle="modal"
            data-target={"#newMemberModel"}
          >
            <i className="fa fa-plus"></i> New Member
          </a>
          <a
            className="btn btn-danger text-white m-t m-l"
            data-toggle="modal"
            data-target={"#removeMemberModel"}
          >
            <i className="fa fa-minus"></i> Remove Member
          </a>
        </div>
      </div>

      {/* Add Member Model */}
      <AddMemberModal parentCallback={handleCallback}/>

      {/* Remove Member Model */}
      <RemoveMemberModel />
    </div>
  );
};

export default MemberList;

添加成员.js

import React, { useState, useEffect } from "react";
import { toast } from "react-toastify";
import DatePicker from "react-datepicker";
import useForm from "react-hook-form";

import { css } from "glamor";
import "react-toastify/dist/ReactToastify.css";
import "react-datepicker/dist/react-datepicker.css";
import "../Styles/ReactDatePicker.css";

const { postMember } = require("../Utils/Service");

const AddMemberModal = ({parentCallback}) => {
  const [date, setDate] = useState(new Date());

  const { handleSubmit, register, errors } = useForm();

  // const handleDateChange = date => {
  //   setDate(date)
  // }
  const onSubmit = (data) => {
    try {
      data.familyId = "5dddf14df965552b3da57be1";
      postMember(data).then(async () => parentCallback(true));
    } catch (error) {
      toast.error("500: Error with Service Call", {
        position: "top-right",
        autoClose: 5000,
        hideProgressBar: false,
        closeOnClick: true,
        pauseOnHover: true,
        draggable: true,
        className: css({
          background: "#ed5565 !important"
        })
      });
    }
  };

  return (
    <div
      className="modal inmodal"
      id={"newMemberModel"}
      tabIndex="-1"
      role="dialog"
      style={{ display: "none" }}
      aria-hidden="true"
    >
      <div className="modal-dialog">
        <div className="modal-content animated fadeIn">
          <div className="modal-header">
            <button type="button" className="close" data-dismiss="modal">
              <span aria-hidden="true">×</span>
              <span className="sr-only">Close</span>
            </button>
            <h4 className="modal-title">New Family Member</h4>
          </div>
          <form onSubmit={handleSubmit(onSubmit)}>
            <div className="modal-body">
              <div className="row">
                <div className="col">
                  <div className="form-group">
                    <label>First Name</label>
                    <input
                      type="text"
                      placeholder="First Name"
                      className="form-control"
                      name="firstName"
                      ref={register({
                        required: true,
                        pattern: {
                          value: /^[a-zA-Z]+$/i,
                          message: "Invalid First Name"
                        }
                      })}
                    />
                    <div className="text-danger">
                      {errors.firstName && errors.firstName.message}
                    </div>
                  </div>
                  <div className="form-group">
                    <label className="font-normal">Birthday</label>
                    <div className="input-group date">
                      {/* <DatePicker
                        selected={date}
                        onChange={handleDateChange}
                        placeholderText="Click to select a date"
                        isClearable
                        peekNextMonth
                        showMonthDropdown
                        showYearDropdown
                        dropdownMode="select"
                        ref={e =>register({
                          name: "Birthday",
                          required: false
                        })}
                      /> */}
                      <input
                        type="text"
                        placeholder="01/01/01"
                        className="form-control"
                        name="birthDate"
                        ref={register({
                          required: false
                        })}
                      />
                    </div>
                  </div>
                </div>
                <div className="col">
                  <div className="form-group">
                    <label>Last Name</label>
                    <input
                      type="text"
                      placeholder="Last Name"
                      className="form-control"
                      name="lastName"
                      ref={register({
                        required: true,
                        pattern: {
                          value: /^[a-zA-Z]+$/i,
                          message: "Invalid Last Name"
                        }
                      })}
                    />
                    <div className="text-danger">
                      {errors.lastName && errors.lastName.message}
                    </div>
                  </div>
                  <div className="form-group">
                    <label>Role</label>
                    <select
                      className="custom-select"
                      name="role"
                      ref={register({ required: true })}
                    >
                      <option defaultValue>Select Role</option>
                      <option value="Adult">Adult</option>
                      <option value="Child">Child</option>
                    </select>
                  </div>
                </div>
              </div>
            </div>
            <div className="modal-footer">
              <button
                type="button"
                className="btn btn-white"
                data-dismiss="modal"
              >
                Close
              </button>
              <button type="submit" className="btn btn-primary">
                Add Member
              </button>
            </div>
          </form>
        </div>
      </div>
    </div>
  );
};

export default AddMemberModal;

我可以在控制台的控制台中看到的顺序是:

[Log] get family
[Log] set family list
[Log] [Object, Object, Object, Object, Object, Object, Object, Object, Object, Object] (10)

其返回的对象缺少最近添加的成员。 我曾尝试添加超时,认为这可能是时间问题,但这在此问题上没有变化。

您可以将提交的数据添加到数组中,而不是刷新页面

MemberList.js文件中,将您的handleCallback更改为:

function handleCallback(data){
    const arr = [...familyMembersList];
    let newMember = (
      <Member
        key={data._id}
        index={data._id}
        balance={0}
        firstName={data.firstName}
        lastName={data.lastName}
        birthday={data.birthday}
        role={data.role}
      />
    )
    arr.push(newMember);
    console.log(arr);
    setFamilyMembersList(arr);
    setLoading(false);
  }

并在您的AddMember.js中将onSubmit方法更改为:

const onSubmit = (data) => {
    try {
        data.familyId = "5dddf14df965552b3da57be1";
        postMember(data).then(async () => parentCallback(data));
    } catch (error) {
    ...
    }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM