簡體   English   中英

功能組件中的新道具不會重新渲染

[英]New props in functional components does not re-render

我目前在收到新道具時無法更新的功能組件出現問題。 我想澄清我的心理 model 並在查看 react 網站的 備忘單后,如果新道具保存在 state 中,則應該更新組件,對嗎?

考慮以下代碼:

const defaultStart = dayjs().startOf("month").format("YYYY-MM-DD");
const defaultEnd = dayjs().endOf("month").format("YYYY-MM-DD");

function IncidentList({
  incidentsList,
  requestIncidents,
  selectedLoc,
  selectedLoc,
  startDate = defaultStart,
  endDate = defaultEnd,
}) {
  const [selectedEndDate, handleEndDateChange] = useState(endDate);
  const [selectedStartDate, handleStartDateChange] = useState(startDate);

  useEffect(() => {
  ┊ const payload = {
  ┊ ┊ location: selectedLoc,
  ┊ ┊ start_date: dayjs(selectedStartDate).format("YYYY-MM-DD"),
  ┊ ┊ end_date: dayjs(selectedEndDate).format("YYYY-MM-DD"),
  ┊ };
  ┊ requestIncidents(payload);
  }, [requestIncidents, selectedEndDate, selectedStartDate]);

   return (
   ┊ <div className="container sm:p-8 md:p-16">
   ┊ ┊ <MaterialTable
   ┊ ┊ ┊ columns={columns}
   ┊ ┊ ┊ data={incidentsList}
   ┊ ┊ ┊ title="Incident list"
   ┊ ┊ ┊ actions={actions}
   ┊ ┊ ┊ options={{
   ┊ ┊ ┊ ┊ pageSize: 20,
   ┊ ┊ ┊ }} 
 ┊ ┊ ┊ components={{
 ┊ ┊ ┊ ┊ Toolbar: (props) => (
 ┊ ┊ ┊ ┊ ┊ <div className="p-8">
 ┊ ┊ ┊ ┊ ┊ ┊ <MTableToolbar {...props} />
 ┊ ┊ ┊ ┊ ┊ ┊ <div className="ml-8 p-8 border-1 w-1/2">
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ <div className="flex flex-row">
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ <p className="text-lg font-semibold">Filter Using:</p>
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ </div>
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ <div className="flex flex-row -mx-4">
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ <div className="px-8">
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ <DatePicker
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ format="YYYY-MM-DD"
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ label="Minimum Date"
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ inputVariant="outlined"
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ minDate={new Date("2015-01-01")}
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ maxDate={dayjs().format()}
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ value={selectedStartDate}
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ onChange={handleStartDateChange}
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ />
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ </div>
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ <div className="px-8">
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ <DatePicker
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ format="YYYY-MM-DD"
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ label="Maximum Date"
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ inputVariant="outlined"
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ minDate={selectedStartDate}
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ maxDate={dayjs().format()}
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ value={selectedEndDate}
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ onChange={handleEndDateChange}
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ />
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ </div>
 ┊ ┊ ┊ ┊ ┊ ┊ ┊ </div>
 ┊ ┊ ┊ ┊ ┊ ┊ </div>
 ┊ ┊ ┊ ┊ ┊ </div>
 ┊ ┊ ┊ ┊ ),
 ┊ ┊ ┊ }} />

const mapStateToProps = (state) => ({
  incidentsList: state.incident.incidents,
  selectedLoc: state.loc.selectedLoc,
});

IncidentList.propTypes = {
  incidentsList: PropTypes.arrayOf(PropTypes.object),
  requestIncidents: PropTypes.func,
  selectedLoc: PropTypes.number,
  endDate: PropTypes.string,
  startDate: PropTypes.string,
};

當我同時更新startDateendDate時,上面的代碼不會更新 state 。 我必須調用useEffect才能同步。 我想當我們收到新的道具時,組件應該重新渲染,因此調用useState將其設置為默認值。

我想知道為什么我必須添加此代碼才能使其在我更新道具時期望我的組件更新的地方工作。 添加的代碼:


  useEffect(() => {
  ┊ if (startDate && endDate) {
  ┊ ┊ handleEndDateChange(endDate);
  ┊ ┊ handleStartDateChange(startDate);
  ┊ }
  }, [startDate, endDate]);

如果任何道具更新, IncidentList將重新渲染。

但是,您似乎沒有使用startDateendDate 相反,您只是設置selectedStartDateselectedEndDate的初始值,這不是重新渲染的一部分,因此當startDateendDate更新時selectedStartDateselectedEndDate不會更新。

嘗試直接使用startDateendDate ,除非您有一些邏輯( if (startDate && endDate) ??),在這種情況下,您將需要您添加的 state 對象。

您需要從父母的 state 傳遞道具。

例如:

import React from 'react';
import IncidentList from './IncidentList';
const IncidentListContainer = () => {
   const [startDate, setStartDate] = React.useState(new Date);
   const [endDate, setEndDate] = React.useState(new Date);
   setStartDate(newDate); // this will update child
   return (
      <IncidentList 
         startDate={startDate}
         endDate={endDate}
         // other props
      />
   );
}

相反,以下內容將不起作用:

const startDate = new Date;
const endDate = new Date;
changeDatesLater(startDate, endDate); // this won't work
const IncidentListContainer = () => {
   return (
      <IncidentList 
         startDate={startDate}
         endDate={endDate}
         // other props
      />
   );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM