数据更改时 useEffect 不会触发

useEffect doesn't fire when data change

我创建了一个带过滤器的 table。每件事都运作良好。 后来,我想将过滤器从 material ui 更改为核心 ui。 我创建了一个过滤器并尝试在移动之前对其进行测试。但它没有用。 useEffect 无论如何都不会触发的问题。我什至尝试放置变量 x 并在单击发生时递增它,并将其作为 useEffect 中的参数。但什么也没发生。

函数 renderTableData(每次我选择过滤器时都会呈现我的 table) function onSiteChange(当我选择一个过滤器时触发的函数) 函数 UpdateTableData(将第一次提供我的 table)

谢谢

******************************** RENDER TABLE *********************
  const renderTableData = () => {
    return (
      <div className="selectTable">
        <div
          className="ag-theme-alpine"
          style={{
            height: "75vh",
            width: "110wh",
            alignContent: "center",
            alignItems: "center",
            alignSelf: "center",
          }}
        >
          <AgGridReact
            rowData={dataFiltred}
            rowHeight={rowHeight}
            rowStyle={{ textAlign: "center" }}
          >
            <AgGridColumn field="Pseudo"></AgGridColumn>
            <AgGridColumn field="Site"></AgGridColumn>
            <AgGridColumn field="Langue"></AgGridColumn>
            <AgGridColumn field="Actif_Inactif"></AgGridColumn>
            <AgGridColumn field="Date_Formation"></AgGridColumn>
            <AgGridColumn field="Formateur"></AgGridColumn>
            <AgGridColumn field="Nature_Formation"></AgGridColumn>
            <AgGridColumn field="Durée"></AgGridColumn>
            <AgGridColumn field="Action"></AgGridColumn>
          </AgGridReact>
        </div>
      </div>
    );
  };

  // ********************************* logic *********************

  function onSiteChange(value, type) {
    if (type === "Site") {
      value.forEach((elem) => {
        rowData.forEach((data) => {
          if (data["Site"] === elem["value"]) {
            dataSiteFiltred.push(data);
          }
        });
      });
      console.log(dataSiteFiltred);
      if (dataSiteFiltred.length) {
        dataFiltred = [];
        dataSiteFiltred.forEach((elem94) => {
          dataFiltred.push(elem94);
        });
      }
    }
  }

  function updateTableData() {
    if (!dataFiltred.length) {
      rowData.forEach((elem) => {
        dataFiltred.push(elem);
      });
    }
  }
  updateTableData();

  useEffect(
    () => {
      renderTableData();
      console.log("fired");
    },
    [dataFiltred],
    [dataSiteFiltred]
  );

您没有使用任何状态,或更改不会导致重新渲染和相应使用效果的状态或道具

您需要将 dataFiltreddataSiteFiltred 存储在一个状态中,然后更新它以导致 re-rendering/useEffect.

像这样:

const [dataFiltred, setDataFiltred] = useState([]);

并像这样更新你的状态:

setDataFiltred([...dataFiltred, elem94]);

useEffect 只接受一个依赖数组

因此,如果您想观看两个阵列,请执行以下操作:

 useEffect(
    () => {
      renderTableData();
      console.log("fired");
    },[dataFiltred, dataSiteFiltred]
  );

万一改变数组后没有激活useEffect,可以考虑使用Array.length

 useEffect(
    () => {
      renderTableData();
      console.log("fired");
    },[dataFiltred.length, dataSiteFiltred.length]
  );

所以这是以前的工作代码。 基本相同

useEffect(
    () => {
      renderTableData();
    },
    [dataSiteFiltred],
    [dataMonthFiltred],
    [dataLangueFiltred],
    [dataNatureFiltred],
    [dataActifInactifFiltred],
    [dataFormateurFiltred],
    [dataFiltred]
  );

  function updateTableData() {
    var localData = [];
    if (!dataFiltred.length) {
      rowData.forEach((elem) => {
        dataFiltred.push(elem);
      });
    }
    if (
      dataFormateurFiltred.length ||
      dataActifInactifFiltred.length ||
      dataLangueFiltred.length ||
      dataMonthFiltred.length ||
      dataSiteFiltred.length ||
      dataNatureFiltred.length
    ) {
      localData = [
        ...dataFormateurFiltred,
        ...dataActifInactifFiltred,
        ...dataLangueFiltred,
        ...dataMonthFiltred,
        ...dataSiteFiltred,
        ...dataNatureFiltred,
      ];
      var dataForUser = [];
      dataFiltred = [];
      var exist = true;
      localData.forEach((elem) => {
        if (site.length && elem["Site"] !== site) {
          exist = false;
        }
        if (month.length && elem["Date_Formation"] !== month) {
          exist = false;
        }
        console.log(langue);
        if (langue.length && elem["Langue"] !== langue) {
          exist = false;
        }
        if (actifInactif.length && elem["Actif_Inactif"] !== actifInactif) {
          exist = false;
        }
        if (formateur.length && elem["Formateur"] !== formateur) {
          exist = false;
        }
        if (nature.length && elem["Nature_Formation"] !== nature) {
          exist = false;
        }
        if (exist === true) {
          dataForUser.push(elem);
        }
      });
      const seen = new Set();
      dataFiltred = dataForUser.filter((el) => {
        const duplicate = seen.has(el.id);
        seen.add(el.id);
        return !duplicate;
      });
    }
  }
  updateTableData();

这是完整的组件。

import React, { useEffect, useState, useRef } from "react";
import {
  CCard,
  CFormGroup,
  CCol,
  CLabel,
  CRow,
  CCardHeader,
  CButton,
  CCollapse,
} from "@coreui/react";

// AG GRID importaion
import { render } from "react-dom";
import { AgGridColumn, AgGridReact } from "ag-grid-react";
import "ag-grid-community/dist/styles/ag-grid.css";
import "ag-grid-community/dist/styles/ag-theme-alpine.css";

import CIcon from "@coreui/icons-react";
import { freeSet } from "@coreui/icons";
import Select from "react-select";

export default function ReacpFormationV2() {
  // golbal variables
  // var dataFiltred = []; // where we will push all filtred data
  // var dataSiteFiltred = []; // contain the data filtred using site
  // var siteFilterActive = false;
  // var dataMonthFiltred = []; // contain the data filtred using Month
  // var monthFilterActive = false;
  // var dataLangueFiltred = []; // contain the data filtred using Langue
  // var langueFilterActive = false;
  // var dataNatureFiltred = []; // contain the data filtred using Nature
  // var natureFilterActive = false;
  // var dataActifInactifFiltred = []; // contain the data filtred using Actif/Inactif
  // var actifInactifFilterActive = false;
  // var dataFormateurFiltred = []; // contain the data filtred using Formateur
  // var formateurFilterActive = false;
  //filtre collapse settings
  const [collapseFilter, setCollapseFilter] = useState(false);
  const toggleFilter = (e) => {
    setCollapseFilter(!collapseFilter);
    e.preventDefault();
  };
  // hooks
  const selectInputSiteRef = useRef();
  const selectInputMonthRef = useRef();
  const selectInputLangueRef = useRef();
  const selectInputNatureRef = useRef();
  const selectInputActifInactifRef = useRef();
  const selectInputFormateurRef = useRef();

  const [dataFiltred, setDataFiltred] = useState([]);
  const [dataSiteFiltred, setDataSiteFiltred] = useState([]);
  const [siteFilterActive, setSiteFilterActive] = useState(false);
  const [dataMonthFiltred, setDataMonthFilter] = useState([]);
  const [monthFilterActive, setMonthFilterActive] = useState(false);
  const [dataLangueFiltred, setDataLangueFiltred] = useState([]);
  const [langueFilterActive, setLangueFilterActive] = useState(false);
  const [dataNatureFiltred, setDataNatureFiltred] = useState([]);
  const [natureFilterActive, setNatureFilterActive] = useState(false);
  const [dataActifInactifFiltred, setDataActifInactifFiltred] = useState([]);
  const [actifInactifFilterActive, setActifInactifFilterActive] =
    useState(false);
  const [dataFormateurFiltred, setDataFormateurFiltred] = useState([]);
  const [formateurFilterActive, setFormateurFilterActive] = useState(false);

  // data
  const dataSite = [
    { value: "Sousse", label: "Sousse" },
    { value: "Tunis", label: "Tunis" },
    { value: "France", label: "France" },
  ];

  const dataMonth = [
    { value: "January", label: "January" },
    { value: "February", label: "February" },
    { value: "March", label: "March" },
    { value: "April", label: "April" },
    { value: "May", label: "May" },
    { value: "June", label: "June" },
    { value: "July", label: "July" },
    { value: "August", label: "August" },
    { value: "September", label: "September" },
    { value: "October", label: "October" },
    { value: "November", label: "November" },
    { value: "December", label: "December" },
  ];
  const dataLangue = [
    { value: "FR", label: "FR" },
    { value: "EN", label: "EN" },
    { value: "ES", label: "ES" },
  ];
  const dataNature = [
    { value: "upport Divinatoire", label: "upport Divinatoire" },
    { value: "Commerciale", label: "Commerciale" },
    { value: "Communication", label: "upport Divinatoire" },
    { value: "Culture Générale", label: "Culture Générale" },
    { value: "Divers", label: "Divers" },
  ];

  const dataActifInactif = [
    { value: "Actif", label: "Actif" },
    { value: "Inactif", label: "Inactif" },
  ];

  const dataFormateur = [
    { value: "SEMER", label: "SEMER" },
    { value: "Houssem", label: "Houssem" },
    { value: "Mehdi", label: "Mehdi" },
    { value: "Stéphane", label: "Stéphane" },
    { value: "Bassem", label: "Bassem" },
  ];

  // ********************************* TABLE DATA *********************
  const rowHeight = 50;
  const rowData = [
    {
      Pseudo: "Voy1",
      Site: "Tunis",
      Langue: "FR",
      Actif_Inactif: "Actif",
      Date_Formation: "January",
      Formateur: "Houssem",
      Nature_Formation: "Support Divinatoire",
      Durée: "4h",
      Action: "Visulaiser",
    },
    {
      Pseudo: "Voy2",
      Site: "Sousse",
      Langue: "EN",
      Actif_Inactif: "Inactif",
      Date_Formation: "",
      Formateur: "Si SEMER",
      Nature_Formation: "Commerciale",
      Durée: "",
      Action: "troller",
    },
    {
      Pseudo: "Voy3",
      Site: "France",
      Langue: "FR",
      Actif_Inactif: "Actif",
      Date_Formation: "February",
      Formateur: "Stéphane",
      Nature_Formation: "Communication",
      Durée: "03",
      Action: "Divers",
    },
    {
      Pseudo: "Voy4",
      Site: "",
      Langue: "ES",
      Actif_Inactif: "",
      Date_Formation: "",
      Formateur: "",
      Nature_Formation: "Culture Générale",
      Durée: "",
      Action: "Divers",
    },
    {
      Pseudo: "Voy5",
      Site: "",
      Langue: "",
      Actif_Inactif: "",
      Date_Formation: "",
      Formateur: "",
      Nature_Formation: "Divers",
      Durée: "",
      Action: "",
    },
    {
      Pseudo: "Voy6",
      Site: "",
      Langue: "ES",
      Actif_Inactif: "",
      Date_Formation: "",
      Formateur: "",
      Nature_Formation: "",
      Durée: "",
      Action: "",
    },
    {
      Pseudo: "Voy7",
      Site: "",
      Langue: "ES",
      Actif_Inactif: "",
      Date_Formation: "",
      Formateur: "Mehdi",
      Nature_Formation: "",
      Durée: "",
      Action: "",
    },
    {
      Pseudo: "Voy8",
      Site: "",
      Langue: "",
      Actif_Inactif: "",
      Date_Formation: "",
      Formateur: "SEMER",
      Nature_Formation: "",
      Durée: "",
      Action: "",
    },
    {
      Pseudo: "Voy9",
      Site: "",
      Langue: "EN",
      Actif_Inactif: "",
      Date_Formation: "",
      Formateur: "Bassem",
      Nature_Formation: "",
      Durée: "",
      Action: "",
    },
    {
      Pseudo: "Voy10",
      Site: "",
      Langue: "EN",
      Actif_Inactif: "",
      Date_Formation: "",
      Formateur: "",
      Nature_Formation: "",
      Durée: "",
      Action: "",
    },
    {
      Pseudo: "Voy11",
      Site: "",
      Langue: "EN",
      Actif_Inactif: "",
      Date_Formation: "",
      Formateur: "",
      Nature_Formation: "",
      Durée: "",
      Action: "",
    },
    {
      Pseudo: "Voy12",
      Site: "",
      Langue: "FR",
      Actif_Inactif: "",
      Date_Formation: "",
      Formateur: "",
      Nature_Formation: "",
      Durée: "",
      Action: "",
    },
  ];

  // ********************************* RENDER TABLE *********************
  const renderTableData = () => {
    return (
      <div className="selectTable">
        <div
          className="ag-theme-alpine"
          style={{
            height: "75vh",
            width: "110wh",
            alignContent: "center",
            alignItems: "center",
            alignSelf: "center",
          }}
        >
          <AgGridReact
            rowData={dataFiltred}
            rowHeight={rowHeight}
            rowStyle={{ textAlign: "center" }}
          >
            <AgGridColumn field="Pseudo"></AgGridColumn>
            <AgGridColumn field="Site"></AgGridColumn>
            <AgGridColumn field="Langue"></AgGridColumn>
            <AgGridColumn field="Actif_Inactif"></AgGridColumn>
            <AgGridColumn field="Date_Formation"></AgGridColumn>
            <AgGridColumn field="Formateur"></AgGridColumn>
            <AgGridColumn field="Nature_Formation"></AgGridColumn>
            <AgGridColumn field="Durée"></AgGridColumn>
            <AgGridColumn field="Action"></AgGridColumn>
          </AgGridReact>
        </div>
      </div>
    );
  };

  // ********************************* logic *********************

  function onSiteChange(value, type) {
    if (type === "Site") {
      value.forEach((elem) => {
        rowData.forEach((data) => {
          if (data["Site"] === elem["value"]) {
            setDataSiteFiltred([...dataSiteFiltred, data]);
          }
        });
      });
    }
    if (dataSiteFiltred.length) {
      setDataFiltred([]);
      dataSiteFiltred.forEach((elem) => {
        setDataFiltred([...dataFiltred, elem]);
      });
    }
  }

  function updateTableData() {
    if (!dataFiltred.length) {
      rowData.forEach((elem) => {
        setDataFiltred([...dataFiltred, elem]);
        console.log(dataFiltred);
      });
    }
  }
  updateTableData();

  useEffect(() => {
    renderTableData();
  }, [dataFiltred, dataSiteFiltred]);

  return (
    <>
      <CCard>
        <CCardHeader>
          <div
            style={{
              textAlign: "center",
              fontSize: "large",
              fontWeight: "bold",
            }}
          >
            Récapitulatif de formation continue
          </div>
        </CCardHeader>
      </CCard>
      <CCard>
        <CCardHeader>
          <CFormGroup row>
            <CCol md="6">
              <CButton
                className="btn-sm"
                size="sm"
                variant="outline"
                color="info"
                onClick={toggleFilter}
              >
                <CIcon size={"sm"} content={freeSet.cilFilter}></CIcon>
                Afficher Filtre
              </CButton>
            </CCol>
          </CFormGroup>
          <CFormGroup>
            <CCollapse show={collapseFilter}>
              <CFormGroup>
                <CCol md="6 mt-1">
                  <CRow>
                    <CCol md="2 mt-1">
                      <CLabel>Site:</CLabel>
                    </CCol>
                    <CCol md="8 mt-0">
                      <Select
                        isMulti
                        name="selectSite"
                        options={dataSite}
                        ref={selectInputSiteRef}
                        onChange={(value) => onSiteChange(value, "Site")}
                      />
                    </CCol>
                  </CRow>
                  <CRow>
                    <CCol md="2 mt-1">
                      <CLabel>Month:</CLabel>
                    </CCol>
                    <CCol md="8 mt-0">
                      <Select
                        isMulti
                        name="selectMonth"
                        id="selectMonth"
                        options={dataMonth}
                        ref={selectInputMonthRef}
                      />
                    </CCol>
                  </CRow>
                  <CRow>
                    <CCol md="2 mt-1">
                      <CLabel>Langue:</CLabel>
                    </CCol>
                    <CCol md="8 mt-0">
                      <Select
                        isMulti
                        name="SelectLangue"
                        options={dataLangue}
                        ref={selectInputLangueRef}
                      />
                    </CCol>
                  </CRow>
                  <CRow>
                    <CCol md="2 mt-1">
                      <CLabel>Nature:</CLabel>
                    </CCol>
                    <CCol md="8 mt-0">
                      <Select
                        isMulti
                        name="selectNature"
                        options={dataNature}
                        ref={selectInputNatureRef}
                      />
                    </CCol>
                  </CRow>
                  <CRow>
                    <CCol md="2 mt-1">
                      <CLabel>Actif/Inactif:</CLabel>
                    </CCol>
                    <CCol md="8 mt-0">
                      <Select
                        isMulti
                        name="selectAcifInactif"
                        options={dataActifInactif}
                        ref={selectInputActifInactifRef}
                      />
                    </CCol>
                  </CRow>
                  <CRow>
                    <CCol md="2 mt-1">
                      <CLabel>Formateur:</CLabel>
                    </CCol>
                    <CCol md="8 mt-0">
                      <Select
                        isMulti
                        name="selectFormateur"
                        options={dataFormateur}
                        ref={selectInputFormateurRef}
                      />
                    </CCol>
                  </CRow>
                </CCol>
              </CFormGroup>
            </CCollapse>
          </CFormGroup>
        </CCardHeader>
      </CCard>

      <div className="formationContinueContainer">
        {/* ********************** Table ****************** */}

        {renderTableData()}
      </div>
    </>
  );
}