React / Redux应用程序需要MaterialUI Spinning loader帮助

时间:2019-10-15 21:03:18

标签: reactjs react-redux

Tag Assistant

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

   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("")
    }

我的课:

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

对此不确定,但遵循约定:       componentDidMount(){         const {dispatch,id} = this.props;

  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: ''
    }

   }

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

   }

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

检查报告或数据包:

     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>

这是旋转加载程序应该执行的操作,并且一旦加载数据就消失了-当前,它一直在旋转,并且数据从未加载,即使我可以看到数据已成功从reducer返回: / p>

            { 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>

1 个答案:

答案 0 :(得分:1)

isLoading变量未在您的渲染方法中定义。我看到您已在组件的状态和化简器中定义了它。我假设您正在引用状态中的一个(因为您说它一直在旋转,所以可能是这种情况)。您在isLoading中将组件的handleSubselection设置为true,您有以下代码段:

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

此代码将isLoading设置为true,而不是调度ReportGetAllChannels。但是,您组件的状态不会被更新。我不知道ReportGetAllChannels的作用,但我猜想它会将自己的isLoading设置为false。哪个是不同的变量。

另外,您可能需要阅读此https://overreacted.io/writing-resilient-components/#principle-1-dont-stop-the-data-flow。将状态映射到道具后,通常需要将它们直接传递给子组件。

编辑: 快速修复:使用this.props.isLoading代替state,然后在您调度的操作中将isLoading设置为true