目前,我的功能组件出现了问题,当它收到新的道具时,它不会更新。我想澄清我的心智模型,在查看了备忘单从react网站,新的道具应该更新的组件,如果它是保存在状态,对吗?
考虑以下代码:
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,
};当我同时更新startDate和endDate时,上面的代码没有更新状态。我必须打电话给useEffect才能同步。我认为当我们收到新的道具时,组件应该重新呈现,从而召回useState,用默认值来设置它。
我想知道为什么我必须添加这段代码才能让它正常工作,当我更新道具时,我希望组件能够更新。增加的代码:
useEffect(() => {
┊ if (startDate && endDate) {
┊ ┊ handleEndDateChange(endDate);
┊ ┊ handleStartDateChange(startDate);
┊ }
}, [startDate, endDate]);发布于 2020-07-01 03:30:10
如果IncidentList的任何道具被更新,它将重新呈现。
但是,您似乎并没有使用startDate和endDate。相反,您只是设置selectedStartDate和selectedEndDate的初始值,这不是重呈现的一部分,因此selectedStartDate和selectedEndDate在startDate和endDate更新时不会更新。
尝试直接使用startDate和endDate,除非您有某种逻辑(if (startDate && endDate) ??),在这种情况下,您将需要添加的状态对象。
发布于 2020-07-01 03:28:55
你需要从父母的状态传递道具。
例如:
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
/>
);
}https://stackoverflow.com/questions/62669115
复制相似问题