这是我的代码: 顶级组件(即RosterScheduler.js)的源代码如下:
import {Col,Container,Row} from 'react-bootstrap';
import {useEffect,useState} from 'react';
import CalendarUtility from '../../../utils/calendar/CalendarUtility';
import MonthPicker from '../../monthPicker/MonthPicker';
import Roster from '../../../utils/Roster';
import RosterSchedulerTable from '../../tables/rosterSchedulerTable/RosterSchedulerTable';
export default function RosterScheduler(props){
const [rosterMonth,setRosterMonth]=useState(new Date());
const[rosterSchedulerData,setRosterSchedulerData]=useState();
let monthPickerMinDate=props.systemParam.monthPickerMinDate;
//console.log(monthPickerMinDate);
monthPickerMinDate=new Date(monthPickerMinDate.year,monthPickerMinDate.month-1,monthPickerMinDate.date);
//console.log(props);
//console.log(props.systemParam.monthSelectorMinDate);
let updateMonth=(year,month)=>{
//console.log("updateMonth="+year+","+month);
let newDate=new Date();
newDate.setFullYear(year);
newDate.setMonth(month);
setRosterMonth(newDate);
}
let systemParam=props.systemParam;
useEffect(()=>{
const getData = async () => {
let calendarUtility=new CalendarUtility();
let monthlyCalendar=calendarUtility.getMonthlyCalendar(rosterMonth.getFullYear(),rosterMonth.getMonth());
let roster = new Roster();
let rosterData = await roster.getRosterSchedulerList(rosterMonth.getFullYear(),rosterMonth.getMonth()+1);
let activeShiftInfoList= await roster.getAllActiveShiftInfo();
setRosterSchedulerData(
{
"activeShiftInfoList":activeShiftInfoList,
"calendarUtility":calendarUtility,
"monthlyCalendar":monthlyCalendar,
"rosterData":rosterData,
"systemParam":systemParam
}
)
}
getData();
},[rosterMonth]);
return (
<div className="App p-1">
<Container fluid={true} className="tableContainer">
<Row>
<Col className="font-weight-bold text-center tableCaption" md={12} lg={12} sm={12} xl={12} xs={12}>
<u>Computer Operation Support Services Team Roster</u>
</Col>
</Row>
<Row>
<Col md={12} lg={12} sm={12} xl={12} xs={12}>
<MonthPicker
minDate={monthPickerMinDate}
onSelect={updateMonth} />
</Col>
</Row>
<Row>
<Col className="d-flex justify-content-center p-0" md={12} lg={12} sm={12} xl={12} xs={12}>
{rosterSchedulerData && <RosterSchedulerTable rosterSchedulerData={rosterSchedulerData}/>}
</Col>
</Row>
</Container>
</div>
)
}
RosterSchedulerTable.js 源码如下:
import {useState} from 'react';
import RosterWebContext from '../../../RosterWebContext';
import RosterSchedulerTableBody from './rosterSchedulerTableBody/RosterSchedulerTableBody';
export default function RosterSchedulerTable(props){
const [hightLightCellIndex, setHightLightCellIndex] = useState(-1);
const [rosterData,setRosterData]=useState(props.rosterSchedulerData.rosterData);
let activeShiftInfoList=props.rosterSchedulerData.activeShiftInfoList;
let calendarUtility=props.rosterSchedulerData.calendarUtility;
let monthlyCalendar=props.rosterSchedulerData.monthlyCalendar;
let systemParam=props.rosterSchedulerData.systemParam;
let contextValue={
activeShiftInfoList,
calendarUtility,
hightLightCellIndex,
monthlyCalendar,
rosterData,
setHightLightCellIndex,
setRosterData,
systemParam
};
return (
<table id="rosterTable">
<RosterWebContext.Provider value={contextValue}>
<RosterSchedulerTableBody/>
</RosterWebContext.Provider>
</table>
);
}
RosterSchedulerTableBody.js 源代码如下:
import {useContext,useEffect,useState} from 'react';
import RosterSchedulerRow from './RosterSchedulerRow';
import VacantShiftRow from './VacantShiftRow';
export default function RosterSchedulerTableBody(){
let {rosterData} = useContext(RosterWebContext);
let rowList = [];
console.log("data:"+rosterData.rosterList[1].shiftList.length);
return (
<tbody>
{rowList}
</tbody>
);
}
这是 RosterWebContext.js 的内容:
import React from 'react'
const RosterWebContext = React.createContext({});
export default RosterWebContext
页面加载完毕后,rosterData
和RosterSchedulerTable
中RosterSchedulerTableBody
的内容相同,
但是,当用户从 MonthPicker 中选择月份时,rosterData
中的状态变量 RosterSchedulerTable
应该被更新,然后它应该更新 rosterData
中 RosterSchedulerTableBody
的内容,不幸的是,rosterData
中 RosterSchedulerTableBody
的内容没有更新。
因为 roster.getRosterSchedulerList 和 roster.getAllActiveShiftInfo 方法都是从服务器获取数据,所以我无法在 stackblitz 上演示这个问题。
你能告诉我如何解决这个问题吗?
答案 0 :(得分:0)
useState(initialState)
对安装组件后后续渲染中 initialState
的变化不敏感,因此 rosterData
不会在 props.rosterSchedulerData.rosterData
发生变化时发生变化。
如果您希望状态反映对 rosterSchedulerData.rosterData
组件中 RosterScheduler
的更改,解决方案是再次 lift your state。
答案 1 :(得分:0)
最后,我让它正常工作了。
RosterSchedulerTable.js 源码如下:
import {useState} from 'react';
import RosterWebContext from '../../../RosterWebContext';
import RosterSchedulerTableBody from './rosterSchedulerTableBody/RosterSchedulerTableBody';
import TableHeader from '../tableHeader/TableHeader';
export default function RosterSchedulerTable(props){
const [hightLightCellIndex, setHightLightCellIndex] = useState(-1);
let activeShiftInfoList=props.rosterSchedulerData.activeShiftInfoList;
let calendarUtility=props.rosterSchedulerData.calendarUtility;
let monthlyCalendar=props.rosterSchedulerData.monthlyCalendar;
let rosterData=props.rosterSchedulerData.rosterData;
let systemParam=props.rosterSchedulerData.systemParam;
useEffect(()=>{
setRosterData(props.rosterSchedulerData.rosterData);
},[props.rosterSchedulerData.rosterData])
let contextValue={
activeShiftInfoList,
calendarUtility,
hightLightCellIndex,
monthlyCalendar,
rosterData,
setHightLightCellIndex,
systemParam
};
return (
<table id="rosterTable">
<RosterWebContext.Provider value={contextValue}>
<TableHeader noOfPrevDate={systemParam.noOfPrevDate}/>
<RosterSchedulerTableBody/>
</RosterWebContext.Provider>
</table>
);
}
RosterSchedulerTableBody.js 源码如下:
import {useContext,useEffect,useState} from 'react';
import PreferredShiftRow from './PreferredShiftRow';
import RosterSchedulerRow from './RosterSchedulerRow';
import RosterWebContext from '../../../../RosterWebContext';
import VacantShiftRow from './VacantShiftRow';
export default function RosterSchedulerTableBody(){
const[rosterInfo,setRosterInfo]=useState();
let {rosterData} = useContext(RosterWebContext);
let rowList = [];
console.log("info:"+rosterInfo.rosterList[1].shiftList.length);
console.log("data:"+rosterData.rosterList[1].shiftList.length);
return (
<tbody>
{rowList}
</tbody>
);
}
帕特里克,谢谢