0

I need to create one type of cascading interface in which when selected the first option, it will have to a rest api to get the 2nd options depending on the first option selected

For this I selected antd cascader: https://ant.design/components/cascader/

However I get the following error:

(anonymous function)
src/containers/ExtractPageTemplate/index.js:46
  43 |     label: `${targetOption.label} Dynamic 2`,
  44 |     value: 'dynamic2',
  45 |   }];
> 46 |   this.setState({
  47 |     options: [...this.state.options],
  48 |   });
  49 | }, 1000);

My code is like this:

import React, { Component } from 'react';
import { Row, Col, Tabs, Menu, Dropdown, Button, Icon, message } from 'antd';
import PageHeader from '../../components/utility/pageHeader';
import Box from '../../components/utility/box';
import LayoutWrapper from '../../components/utility/layoutWrapper';
import ContentHolder from '../../components/utility/contentHolder';
import basicStyle from '../../settings/basicStyle';
import IntlMessages from '../../components/utility/intlMessages';
import { Cascader } from 'antd';

const options = [{
    value: 'zhejiang',
    label: 'Zhejiang',
    isLeaf: false,
  }, {
    value: 'jiangsu',
    label: 'Jiangsu',
    isLeaf: false,
  }];

export default class extends Component {

    constructor(props) {
        super(props);
        this.state = {options};
    }

    onChange(value, selectedOptions) {
        console.log(value, selectedOptions);
    }

    loadData(selectedOptions){
        const targetOption = selectedOptions[selectedOptions.length - 1];
        targetOption.loading = true;

        // load options lazily
        setTimeout(() => {
          targetOption.loading = false;
          targetOption.children = [{
            label: `${targetOption.label} Dynamic 1`,
            value: 'dynamic1',
          }, {
            label: `${targetOption.label} Dynamic 2`,
            value: 'dynamic2',
          }];
          this.setState({
            options: [...this.state.options],
          });
        }, 1000);
      }


    render(){
        const { rowStyle, colStyle, gutter } = basicStyle;
        const TabPane = Tabs.TabPane;

        return (
        <div>
            <LayoutWrapper>
            <PageHeader>{<IntlMessages id="pageTitles.PageAdministration" />}</PageHeader>
            <Row style={rowStyle} gutter={gutter} justify="start">
            <Col md={12} sm={12} xs={24} style={colStyle}>
                <Box
                title={<IntlMessages id="pageTitles.siteCollectionsTitle" />}
                subtitle={<IntlMessages id="pageTitles.siteCollectionsTitle" />}
                >
                <ContentHolder>
                    <Cascader
                                options={this.state.options}
                                loadData={this.loadData}
                                onChange={this.onChange}
                                changeOnSelect
                    />
                </ContentHolder>
                </Box>
            </Col>
            </Row>
        </LayoutWrapper>
        </div>
        );
  }
}
Luis Valencia
  • 32,619
  • 93
  • 286
  • 506

3 Answers3

2

Your function is not bound to your class. You have 2 solutions :

Convert it to an arrow function, so that the context is automatically bound to your class :

loadData = selectedOptions => {

Or bind it :

constructor(props) {
    super(props);
    this.state = {options};
    this.loadData = this.loadData.bind(this)
}

You can also bind it in your JSX :

<Cascader
    options={this.state.options}
    loadData={this.loadData.bind(this)}
    onChange={this.onChange}
    changeOnSelect
/>

You may get the same problem later with the onChange function

Treycos
  • 7,373
  • 3
  • 24
  • 47
1

Convert your function to an es6 arrow function and it should work then

loadData = (selectedOptions)=>{
     //YOUR CODE HERE
 }
0

Issue looks in your code is that you have not binded this scope to your function. You can bind it in your constructor like below inside constructor -

this.loadData = this.loadData.bind(this);

Or use ES6 format for function like below -

loadData = (selectedOptions) => { }