React/Redux 应用程序需要 MaterialUI 旋转加载器帮助


import { CircularProgress, FormControl, Input, InputLabel } from 
'@material-ui/core';
function toKey(s) {
return s.split("_").map((s, i) => i > 0 ? s.slice(0,1).toUpperCase() + 
s.slice(1, s.length) : s).join("")
}

拆分返回的 json 对象的函数:

function toLabel(s) {
return s.split("_").map((s, i) => s.slice(0,1).toUpperCase() + 
s.slice(1, s.length)).join(" ")
}

我的班级:

class Reports extends Component {
constructor(props) {
super(props);
this.state = {
report: '',
filename: 'my-data.csv',
isLoading: false,
tableHeaderData: [],
reports: [
{ name: 'C3 Report', id: 1, actOn: 'c3'},
{ name: 'C4 Report', id: 2, actOn: 'c4'},
{ name: 'C5 Report', id: 3, actOn: 'c5'}
],
categories: {name: 'Cat 1'},
catSelection: 'Select a Category',
repSelection: 'Select Report Type',
isReportSelected: false,
c4RptFirstInput: '',
c4RptSecondInput: ''
}
}

不确定这一点,但按照惯例: componentDidMount (( { const {dispatch, id} = this.props;

}
handleChange (e) {
// this.setState({ input: e.target.value });
}

这是我用来将页面转换为csv文件的插件:

csvHeader () {
const  data = this.reportData()
if(data.length === 0) return []
const keys = Object.keys(data[0])
return keys.map((k) => {
const label  = toLabel(k)
const key = toKey(k)
return { label, key }
})
}

csvData () {
const  data = this.reportData()
if(data.length === 0) return []
const values = Object.entries(data);
const keys = Object.keys(data[0])
const rows = values.map(entries => {
const record = entries[1];
return keys.reduce((acc, key, i) => {
acc[toKey(key)] = record[key]
return acc
}, {})
});
return rows
}

检查报告或包是否:

reportData(){
switch(this.state.report) {
case 'channels':
return this.props.channels
case 'packages':
return this.props.packages
default:
return []
}
}

不确定这个占位符函数,但从某个地方复制了它:

placeholder () {
return (   
<div>
<h1 className="display-3">Reports</h1>
<p className="lead" cursor="pointer" onClick= 
{this.loadChannelData}>Svc Configuration</p>
</div>
);
}

正在尝试此功能,但不确定如何使用它:

componentWillReceiveProps() {
}
handleCategorySwitch = (e) => {
const name = e.target.name;
const value = e.target.value;
this.setState({ [name]: value});
console.log(`name ${name}, value ${value}`);
}

这是第二组下拉列表的"子选择"发生的地方:

handleSubselection = (e) => {
this.setState({c4RptSecondInput: e.target.value, })
switch( e.target.value) {
case 'input3':
return  this.props.ReportGetAllPackages()
}
}
handleReportSwitch = (e) => {
const selectedAction = e.target.value;
if (selectedAction == 'c3') {
this.setState(prevState => ({
report: 'channels'
,isLoading: true
}), this.props.ReportGetAllChannels)
}
if (selectedAction == 'c4') {
this.setState(prevState => ({
report: 'packages'
}))
}
}

渲染功能:

render () {
const {filename, reports, catSelection, repSelection, isReportSelected, 
c4RptFirstInput, c4RptSecondInput} = this.state;
return (
<div className="reports">
{this.placeholder()}
<div className="flexMode">
<span className="spanFlexMode">
<InputLabel htmlFor="catSelection"></InputLabel>
<Select value={catSelection} name={'catSelection'} 
onChange={(e) => this.handleCategorySwitch(e)}>
<MenuItem value="select">Select Category</MenuItem>
<MenuItem value={'Cat1'}>Cat 1</MenuItem>
<MenuItem value={'Cat2'}>Cat 2 </MenuItem>
<MenuItem value={'Cat3'}>Cat 3 </MenuItem>
</Select>
</span>
<span className="spanFlexMode">
<label>Report Name:</label>
<Select value={repSelection} name="repSelection" 
onChange={(e) => this.handleReportSwitch(e)}>
<MenuItem defaultValue={'select'}>Select 
Report</MenuItem>
{reports && reports.map((report, index) => <MenuItem 
key={index} value={report.actOn}>{report.name}</MenuItem>)} 
</Select>
</span>
</div>

下面是第二组下拉列表,它们根据从上面的选择框中选择的特定字段有条件地显示:

{ this.state.report === 'packages' ?  (
<div>
<span>
<label>Input 1:</label>
<Select name="c4RptFirstInput" value={c4RptFirstInput} 
placeholder={'Select Provider'} onChange={(e) => 
this.handleSubselection(e)}>
<MenuItem value={'Def'}>Select</MenuItem>
<MenuItem value={'Provider'}>Provider</MenuItem>
<MenuItem value={'Region'}>Region</MenuItem>
<MenuItem value={'Zone'}>Zone</MenuItem>
</Select>
</span>
<span className="spanFlexMode">
<label>Input 2:</label>
<Select name="c4RptSecondInput" defaultValue= 
{c4RptSecondInput} value={c4RptSecondInput} onChange={(e) => 
this.handleSubselection(e)}>
<MenuItem value={'Def'}>Select</MenuItem>
<MenuItem value={'input2'}>Input 2</MenuItem>
<MenuItem value={'input3'}>Input 3</MenuItem>
<MenuItem value={'input4'}>Input 4</MenuItem>
</Select>
</span>
</div>
) : null}

<div>
<CSVLink data={this.csvData()} headers={this.csvHeader()} 
filename={filename} target={'_blank'}>
<GetAppIcon />
</CSVLink>

这是旋转加载器应该做它的地方,一旦加载数据就会消失 - 目前它只是继续旋转,即使我可以看到数据已成功从化简器返回,数据也永远不会加载:

{isLoading
? <CircularProgress />
: (
<Table id="t1">
<TableHeaders data={this.csvHeader()} />
<TableContent data={this.csvData()} />
</Table>
)}
</div>
</div>
)
}
}
const mapDispatchToProps = dispatch => {
return {
ReportGetAllChannels: () => dispatch(ReportGetAllChannels()),
ReportGetAllPackages: () => dispatch(ReportGetAllPackages()),
}
}
const defaultState = ({
state: {},
channels: [],
packages: []
,isLoading: false
})
const mapStateToProps = (state=defaultState) => {
return ({
state: state,
channels: state.RptDetailsReducer.data,
packages: state.RptPackagesReducer.data
,isLoading: false
})
}

isLoading变量未在渲染方法中定义。我看到您在组件的状态和减速器中定义了它。我假设您正在引用您所在州的一个(既然您说它一直在旋转,那么情况可能就是这样(。您将组件的isLoading设置为 true,handleSubselection您有以下代码片段:

if (selectedAction == 'c3') {
this.setState(prevState => ({
report: 'channels',
isLoading: true
}), this.props.ReportGetAllChannels)
}

此代码将isLoading设置为 true 而不是调度ReportGetAllChannels。但是,不会更新组件的状态。我不知道ReportGetAllChannels做了什么,但我猜它会将自己的isLoading设置为假。这是不同的变量。

此外,您可能还需要阅读此 https://overreacted.io/writing 弹性组件/#principle-1-不要停止数据流。将状态映射到 props 后,通常希望将它们直接传递给子组件。

编辑: 快速修复:使用 this.props.isLoading 而不是 state,并在调度操作中将 isLoading 设置为 true

最新更新