我有一个包含一些其他组件的组件,这些组件依赖于减速器状态。每当我在组件中运行操作时,它都会多次渲染。最后两个渲染器完全在render函数中,我不知道会发生这种情况。 我尝试使用chrome中的react dev工具跟踪渲染,但不确定为什么或如何发生。一切似乎合乎逻辑,它会运行需要运行的内容,然后在之后再放弃两次。
由于没有任何我可以依赖的变量,所以我不能使用应该组件更新。
还有其他人有与此相关的问题吗?如果是这样,您如何解决这个问题?
主要组成部分
class LoadTable extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.setState({ fetchInProgress: true });
const getJobsPromise = this.props.getJobs(null, null);
const getJobNamesPromise = this.props.getJobNames();
Promise.all([getJobsPromise, getJobNamesPromise])
.then(([jobsRes, jobNamesRes]) => {
if (jobsRes.results.response.length > 0) {
var initStart = jobsRes.results.response[0].ID;
var initEnd = jobsRes.results.response[jobsRes.results.response.length - 1].ID;
var newStart = initStart;
var newEnd = initEnd;
var snewStart = null;
var snewEnd = null;
var sinitStart = null;
var sinitEnd = null;
var filterOn = false;
var searchOn = false;
var pagMax = (Math.ceil(jobsRes.results.response.length / 10) > 0) ? Math.ceil(jobsRes.results.response.length) / 10 : 0;
pagMax = pagMax + 1;
this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, filterOn, searchOn });
}
this.setState({
fetchInProgress: false,
panelOpen: false,
data: jobsRes.results.response || [],
jobNames: jobNamesRes.results.response || [],
});
});
}
runLog(id) {
this.props.runLog(id);
}
openRunLog(logs) {
this.props.findOutput(logs);
}
handleJobName(e) {
if (e.target.value === 'default') {
this.setState({
selectedJName: 0
});
} else {
this.setState({
selectedJName: e.target.value
});
}
}
clearSearch() {
this.setState({ fetchInProgress: true });
this.props.getJobs(null, null)
.then((res) => {
this.setState({
data: res.results.response || [],
fetchInProgress: false,
searchOn: false,
sort: {
column: null,
direction: 'desc',
}
})
});
}
handleSearch(e) {
const { name, value } = e.target;
const { SearchEndLoc, SearchStrtLoc, SearchIntStrt, SearchIntEnd, EndLoc, StartLoc } = this.props;
this.setState({ [name]: value });
var initStart;
var initEnd;
var newStart;
var newEnd;
var pagMax;
var snewStart;
var snewEnd;
var sinitStart;
var sinitEnd;
var searchOn;
var filterOn;
this.setState({ fetchInProgress: true });
if (value.length < 1) {
searchOn = false;
this.props.getJobs(EndLoc, StartLoc)
.then((res) => {
initStart = this.props.initStart;
initEnd = this.props.initEnd;
newStart = StartLoc;
newEnd = EndLoc;
snewStart = null;
snewEnd = null;
sinitStart = null;
sinitEnd = null;
filterOn = false;
pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
pagMax = pagMax + 1;
this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd,searchOn, filterOn});
this.setState({
data: res.results.response || [],
fetchInProgress: false,
Search: '',
panelOpen: false,
searchRNames: [],
sort: {
column: null,
direction: 'desc'
}
})
});
} else {
searchOn = true;
this.props.doSearch(value, SearchEndLoc, SearchStrtLoc)
.then((res) => {
if (res.results.response.length > 0) {
sinitStart = SearchIntStrt === null || SearchIntStrt === undefined ? res.results.response[0].ID : SearchIntStrt;
sinitEnd = SearchIntEnd === null || SearchIntEnd === undefined ? res.results.response[res.results.response.length - 1].ID : SearchIntEnd;
snewStart = sinitStart;
snewEnd = sinitEnd;
newStart = null;
newEnd = null;
initStart = null;
initEnd = null;
filterOn = false;
pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
pagMax = pagMax + 1;
this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, searchOn, filterOn});
}
this.setState({
data: res.results.response || [],
searchRNames: res.results.response || [],
SearchOn: searchOn,
filterOn: filterOn,
panelOpen: true,
fetchInProgress: false,
Search: value,
sort: {
column: null,
direction: 'desc',
}
})
});
}
}
onChangePage(changePage) {
this.setState({ pageOfItems: changePage.pageOfItems });
if (changePage.searchOn === true) {
this.updateOnSearch(changePage);
}
if (changePage.filterOn === true) {
this.updateOnFilter(changePage);
}
if ((changePage.searchOn === false) && (!changePage.filterOn === false)) {
this.updateOnRegular(changePage);
}
}
updateOnSearch(changePage) {
var newStart = changePage.newStart;
var newEnd = changePage.newEnd;
var initStart = changePage.initStart;
var initEnd = changePage.initEnd;
var snewStart = changePage.snewStart;
var snewEnd = changePage.snewEnd;
var sinitStart = changePage.sinitStart;
var sinitEnd = changePage.sinitEnd;
var searchOn = true;
var filterOn = false;
var pagMax;
if ((changePage.snewStart === null) && (changePage.snewEnd === null)) {
this.setState({ fetchInProgress: true });
this.props.doSearch(this.state.Search, changePage.newEnd, changePage.newStart)
.then((res) => {
if (res.results.response.length > 0) {
sinitStart = res.results.response[0].ID;
sinitEnd = res.results.response[res.results.response.length - 1].ID;
snewStart = changePage.sinitStart;
snewEnd = changePage.sinitEnd;
pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
pagMax = pagMax + 1;
this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, searchOn, filterOn });
}
this.setState({
fetchInProgress: false,
searchOn: searchOn,
filterOn: filterOn,
panelOpen: true,
pageOfItems: res.results.response || [],
sort: {
column: null,
direction: 'desc',
}
})
});
}
if ((changePage.snewStart !== null) && (changePage.snewEnd !== null)) {
this.setState({ fetchInProgress: true });
this.props.doSearch(this.state.Search, changePage.snewEnd, changePage.snewStart)
.then((res) => {
if (res.results.response.length > 0) {
snewStart = res.results.response[0].ID;
snewEnd = res.results.response[res.results.response.length - 1].ID;
pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
pagMax = pagMax + 1;
searchOn = false;
this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, searchOn, filterOn });
}
this.setState({
data: res.results.response || [],
fetchInProgress: false,
searchOn: searchOn,
filterOn: filterOn,
panelOpen: true,
pageOfItems: res.results.response || [],
sort: {
column: null,
direction: 'desc',
}
})
});
}
}
updateOnFilter(changePage) {
const { selectedDRan, selectedDStart, selectedDEnd, selectedJName} = this.state;
var newStart = changePage.newStart;
var newEnd = changePage.newEnd;
var initStart = changePage.initStart;
var initEnd = changePage.initEnd;
var snewStart = changePage.snewStart;
var snewEnd = changePage.snewEnd;
var sinitStart = changePage.sinitStart;
var sinitEnd = changePage.sinitEnd;
var searchOn = false;
var filterOn = true;
var pagMax;
if ((snewStart === null) && (snewEnd === null)) {
this.setState({ fetchInProgress: true });
this.props.filterJobs(selectedJName, selectedDRan, selectedDStart, selectedDEnd, snewStart, snewEnd)
.then((res) => {
if (res.results.response.length > 0) {
sinitStart = res.results.response[0].ID;
sinitEnd = res.results.response[res.results.response.length - 1].ID;
snewStart = changePage.sinitStart;
snewEnd = changePage.sinitEnd;
pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
pagMax = pagMax + 1;
searchOn = false;
this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, searchOn, filterOn });
}
this.setState({
fetchInProgress: false,
searchOn: searchOn,
filterOn: filterOn,
panelOpen: true,
pageOfItems: res.results.response || [],
sort: {
column: null,
direction: 'desc',
}
})
});
}
if ((snewStart !== null) && (snewEnd !== null)) {
this.setState({ fetchInProgress: true });
this.props.filterJobs(selectedJName, selectedDRan, selectedDStart, selectedDEnd, snewStart, snewEnd)
.then((res) => {
if (res.results.response.length > 0) {
snewStart = res.results.response[0].ID;
snewEnd = res.results.response[res.results.response.length - 1].ID;
pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
pagMax = pagMax + 1;
searchOn = false;
this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, searchOn, filterOn });
}
this.setState({
data: res.results.response || [],
fetchInProgress: false,
searchOn: searchOn,
filterOn: filterOn,
panelOpen: true,
pageOfItems: res.results.response || [],
sort: {
column: null,
direction: 'desc',
}
})
});
}
}
updateOnRegular(changePage) {
var newStart = changePage.newStart;
var newEnd = changePage.newEnd;
var initStart = changePage.initStart;
var initEnd = changePage.initEnd;
var snewStart = changePage.snewStart;
var snewEnd = changePage.snewEnd;
var sinitStart = changePage.sinitStart;
var sinitEnd = changePage.sinitEnd;
var searchOn = changePage.searchOn;
var filterOn = changePage.filterOn;
var pagMax;
if ((changePage.newStart !== null) && (changePage.newEnd !== null)) {
this.setState({ fetchInProgress: true });
this.props.getJobs(changePage.newEnd, changePage.newStart)
.then((res) => {
if (res.results.response.length > 0) {
newStart = res.results.response[0].ID;
newEnd = res.results.response[res.results.response.length - 1].ID;
snewStart = null;
snewEnd = null;
sinitStart = null;
sinitEnd = null;
pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
pagMax = pagMax + 1;
this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, searchOn, filterOn });
}
this.setState({
fetchInProgress: false,
pageOfItems: res.results.response || [],
sort: {
column: null,
direction: 'desc',
}
})
});
}
}
onFilterChange() {
const { selectedDRan, selectedDStart, selectedDEnd, selectedJName,jobNames } = this.state;
this.setState({ fetchInProgress: true, filterOn: true });
var filterOn = true;
var searchOn = false;
var filterCheck = this.state.filterCheck;
var initEnd;
var initStart
var newStart;
var newEnd;
var pagMax;
if (filterCheck < 1) {
this.props.filterJobs(selectedJName, selectedDRan, selectedDStart, selectedDEnd, null, null)
.then((res) => {
if (res.results.response.length > 0) {
initStart = res.results.response[0].ID;
initEnd = res.results.response[res.results.response.length - 1].ID;
newStart = initStart;
newEnd = initEnd;
pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length) / 10 : 0;
pagMax = pagMax + 1;
this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, selectedDRan, selectedDStart, selectedDEnd, jobNames, searchOn, filterOn });
}
filterCheck = filterCheck + 1;
this.setState({
data: res.results.response || [],
fetchInProgress: false,
filterOn: filterOn,
searchOn: searchOn,
filterCheck: filterCheck,
panelOpen: true,
sort: {
column: null,
direction: 'desc',
}
})
});
} else {
this.props.filterJobs(selectedJName, selectedDRan, selectedDStart, selectedDEnd, this.props.snewEnd, this.props.snewStart)
.then((res) => {
if (res.results.response.length > 0) {
newStart = res.results.response[0].ID;
newEnd = res.results.response[res.results.response.length - 1].ID;
pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length / 10) : 0;
pagMax = pagMax + 1;
this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, selectedDRan, selectedDStart, selectedDEnd, jobNames, searchOn, filterOn });
}
filterCheck = filterCheck + 1;
this.setState({
data: res.results.response || [],
fetchInProgress: false,
filterOn: filterOn,
searchOn: searchOn,
panelOpen: true,
filterCheck: filterCheck,
pageOfItems: res.results.response || [],
sort: {
column: null,
direction: 'desc',
}
})
});
}
}
onFilterClear() {
this.setState({ fetchInProgress: true });
const getJobsPromise = this.props.getJobs(null, null);
const getJobNamesPromise = this.props.getJobNames();
Promise.all([getJobsPromise, getJobNamesPromise])
.then(([jobsRes, jobNamesRes]) => {
if (jobsRes.results.response.length > 0) {
var initStart = jobsRes.results.response[0].ID;
var initEnd = jobsRes.results.response[jobsRes.results.response.length - 1].ID;
var newStart = initStart;
var newEnd = initEnd;
var snewStart = null;
var snewEnd = null;
var sinitStart = null;
var sinitEnd = null;
var filterOn = false;
var searchOn = false;
var pagMax = (Math.ceil(jobsRes.results.response.length / 10) > 0) ? Math.ceil(jobsRes.results.response.length) / 10 : 0;
pagMax = pagMax + 1;
this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, filterOn, searchOn });
}
this.setState({
fetchInProgress: false,
panelOpen: false,
data: jobsRes.results.response || [],
jobNames: jobNamesRes.results.response || [],
});
});
}
render() {
const { data, Search, pageOfItems, searchRNames, fetchInProgress, jobNames, selectedDRan, selectedDStart, selectedDEnd, selectedJName, panelOpen} = this.state;
const { jobRun } = this.props;
return(
<div>
{fetchInProgress ? (
<div className="row row-centered">
<p>Loading.....Please Wait</p>
</div>
</div>
) : (
data.length < 0 ? (
<div className="searchNoContent"><h3>No Data to Display at the moment</h3></div>
</div>
) : (
<div className="row row-centered">
<div className="col-lg-12 col-md-12 col-sm-12 col-xs-12 col-centered">
{!IsEmpty(jobRun) && <Alert color="success">{jobRun}</Alert>}
<div className="wrap-collabsible">
<input id="collapsible" className="toggle tCheck" type="checkbox" value={panelOpen} onChange={this.handleCheckBox} checked={panelOpen} />
<label htmlFor="collapsible" className="lbl-toggle">Filter/Search Jobs</label>
<div className="collapsible-content">
<div className="content-inner">
<div id="Search" className="">
<div className="input-group">
<Autocomplete
getItemValue={(item) => item.Name}
items={searchRNames}
inputProps={{ className: 'form-control searchIte ms', placeholder: 'Search', name: 'Search', autoFocus: true }}
value={Search}
onSelect={(Search, item) => this.setState({ Search, searchRNames: item })}
renderItem={(item, isHighlighted) =>
<div></div>
}
onChange={this.handleSearch}
/>
</div>
</div>
<div className="tableFilter">
<div className='filterArea'>
<div className='filterBody'>
<p className='filterLabel'>Job Name: </p>
<select defaultValue={selectedJName} className='itemList' onChange={this.handleJobName}>
<option key='0' value='0'>--Select--</option>
{jobNames.map((jbName) => <option key={jbName.ID} value={jbName.ID}>{jbName.Name}</option>)} </select> <button type="button" className="btn btn-success jobFilterBtn " onClick={()=>this.onFilterChange()}>Filter Jobs</button> <button type="button" className="btn btn-danger jobFilterBtn " onClick={() => this.onFilterClear()}>Clear Filter</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<table className="table table-striped">
<thead>
<tr>
<th className="columnHeader" onClick={() => this.doSort('name')}>Name</th>
<th className="columnHeader" onClick={() => this.doSort('date')}>Date Ran</th>
<th className="columnHeader" onClick={() => this.doSort('job')}>Job</th>
<th className="columnHeader" onClick={() => this.doSort('start')}>Start</th>
<th className="columnHeader" onClick={() => this.doSort('end')}>End</th>
<th className="columnHeader" onClick={() => this.doSort('status')}>Status</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{
pageOfItems.map(dt => {
return (
</tr>
);
})
}
</tbody>
</table>
<BOPagination items={data} onChangePage={this.onChangePage.bind(this)} />
</div>
</div>
))}
</div>
);
}
}