РЕАКТИРОВАТЬ: преобразовать вложенный массив объектов в линейную форму

Я получаю данные из API с помощью Axios и сохраняю их в переменной состояния реакции.

Затем в моем методе рендеринга я пытаюсь деструктурировать полученные данные (которые представляют собой вложенный массив объектов) в линейную форму и использовать их в моей таблице реакций.

это структура извлеченных данных:

[
    { "uuid": "c47dea20",
        "siteName": "dfsf",
        "systemName": "bl",
        "measurementName": ",nk",
        "statistics": {
          "dateStart": "2020-04-20T00:00:00Z",
          "dateStop": "2020-04-21T00:00:00Z",
          "values": [
            "temperature1",
            "temperature2"
          ],
          "min": [1, 2],
          "max": [10, 11],
          "average": [5, 6],
          "last": [7, 8],
          "bucket_size": "4h",
          "buckets": {
            "term": "count",
            "values": [5,4,4,5,6,6]
          }
        }
      }
]

Вот как я пытаюсь разрушить:

// gives error: TypeError: Cannot read property 'buckets' of undefined

  const {
    measurementsData: {
      statistics: {
        buckets: [{ values: bucketValues }],
      },
    },
  } = this.state;
  console.log(bucketValues);

Ниже приведен полный код моего компонента:

class Table extends Component {
    constructor(props) {
      super(props);
      this.state = {
        measurementsData: [],
        isLoading: false,
        dropdownOpen: false,
      };
    }

    signal = axios.CancelToken.source();

    componentDidMount() {
      this.handleGetmeasurementsDataInfo();
      this.addFilterPlaceholder();
    }

    componentWillUnmount() {
      this.signal.cancel("Api is being canceled");
      // fix Warning: Can't perform a React state update on an unmounted component
      this.setState = (state, callback) => {
        return;
      };
    }

    handleGetmeasurementsDataInfo = async () => {
      this.setState({ isLoading: true });
      await axios
        .get("https://run.mocky.io/v3/d2f89c5b-487f-409c-bf2c-705b7d91e12d")
        .then((response) => {
          // handle success
          console.log("measurement data:", response.data);
          this.setState({ measurementsData: response.data });
        })
        .catch((error) => {
          // handle error
          if (axios.isCancel(error)) {
            console.log("Unable to fetch measurementsData", error.message);
          } else {
            this.setState({ isLoading: false });
          }
        });
    };

    addFilterPlaceholder = () => {
      const filters = document.querySelectorAll("div.rt-th > input");
      for (let filter of filters) {
        filter.placeholder = "Search..";
      }
    };

    toggleDropdown = () => {
      this.setState((state) => {
        return {
          dropdownOpen: !state.dropdownOpen,
        };
      });
    };

    render() {
      const { dropdownOpen, measurementsData } = this.state;

      // gives error: TypeError: Cannot read property 'buckets' of undefined
      const {
        measurementsData: {
          statistics: {
            buckets: [{ values: bucketValues }],
          },
        },
      } = this.state;
      console.log(bucketValues);

      return (
        <>
          <div className="content">
            <Row className="mt-5">
              <Col xs={12} md={12}>
                <Card>
                  <CardHeader>
                    <CardTitle tag="h4">heading</CardTitle>
                    <hr />
                    <Dropdown isOpen={dropdownOpen} toggle={this.toggleDropdown}>
                      <DropdownToggle caret>Ships</DropdownToggle>
                      {measurementsData.map((measurementData) => {
                        return (
                          <DropdownMenu key={measurementData.siteName}>
                            <DropdownItem>
                              {measurementData.siteName}
                              <DropdownItem divider />
                            </DropdownItem>
                          </DropdownMenu>
                        );
                      })}
                    </Dropdown>
                  </CardHeader>
                  <CardBody>
                  <p>static data </p>
                    <Line data={chartExample9.data} />
                  <p>dynamic data </p>
                    <Line data={this.bucketValues} />

                    <ReactTable
                      data={[...measurementsData]}
                      pageSize={
                        measurementsData.length > 10
                          ? 10
                          : measurementsData.length
                      }
                      filterable
                      resizable={true}
                      columns={[
                        {
                          Header: "System",
                          accessor: "systemName",
                        },
                        {
                          Header: "Measurement",
                          accessor: "measurementName",
                        },
                        {
                          Header: "Value",
                          accessor: "statistics.values",
                        },
                        {
                          Header: "Min",
                          accessor: "statistics.min",
                        },
                        {
                          Header: "Max",
                          accessor: "statistics.max",
                        },
                        {
                          Header: "Avg",
                          accessor: "statistics.average",
                        },
                        {
                          Header: "Last",
                          accessor: "statistics.last",
                        },
                        {
                          Header: "Bar",
                          <Line  data={this.bucketValues}  />
                        },
                      ]}
                      showPaginationTop
                      showPaginationBottom={false}
                      className="-striped -highlight"
                    />
                  </CardBody>
                </Card>
              </Col>
            </Row>
          </div>
        </>
      );
    }
  }

  export default Table;

ОБНОВЛЕНИЕ: обновил код деструктуризации ниже, и теперь я получаю"buckets" is undefined

const {
  statistics: {
    buckets: {
      values: [bucketValues],
    },
  },
} = measurementsData;
console.log(bucketValues);

1 ответ

Вы уже поддерживаете состояние загрузки, используйте его для возврата загрузчика и доступа к соответствующим переменным только после того, как данные будут фактически доступны.

Также обратите внимание, что measureData - это массив, а не объект, поэтому вам нужно разрушить его как единое целое. Это предполагает тот факт, что все bucketValues ​​в каждом объекте measureData будут одинаковыми.

constructor(props) {
      super(props);
      this.state = {
        measurementsData: [],
        isLoading: true, // set to true initially
        dropdownOpen: false,
      };
    }


...
render() {
      const { dropdownOpen, measurementsData, isLoading } = this.state;

      if(isLoading) {
          return <div>Loading...</div>
      }

      const {
         measurementsData: [{
         statistics: {buckets: {values: bucketValues}}
        }],
      } = this.state;
      console.log(bucketValues);

Также lineData должен использовать bucketValues и нет this.bucketValues поскольку вы не храните это значение в переменной класса

<Line data={bucketValues} />
Другие вопросы по тегам