簡體   English   中英

無法讀取未定義錯誤的屬性“長度”-ReactJS

[英]Cannot read property 'length' of undefined Error - ReactJS

我基本上是React的初學者。 我有一個儀表板頁面,其中顯示一個React Table。 我有一個自定義按鈕,它將打開一個彈出頁面,該彈出頁面有一些復選框,允許我顯示/隱藏那些React列。 最初,此彈出頁面中的所有復選框均設置為true。 當我取消選中某個列時,該特定列將被禁用。

圖片

這是我的父組件-父頁面是帶有ReactTable的頁面,現在有10列,而不是圖中的8列。

import React, { Component } from 'react';
import { connect } from 'react-redux';
import ReactTable from 'react-table';
import LoadingComponent from '../shared/loading/LoadingComponent';
import InputComponent from '../shared/input/InputComponent';
import { makeData } from '../../util/Utils';
import CustomizedView from './customized_view/CustomizedView';

import filter from '../../assets/svg/filter.svg';
import config from '../../../framework/config';
//import EnquiryDetails from './enquiry_details/enquiryDetails';

const searchIcon = config.assetUrl + '/table_filter/svg/search-icon.svg';


class Dashboard extends Component {
  constructor(props) {
    super(props);

    this.state = {
      filterState: {},
      data: makeData(),
      searchText: '',
      isFilterOpen: false,
      isCustomizedOpen: false,
      isFiltered: false,
      isSearched: false,
      searchedTableData: [],
      filteredTableData: [],
      filterItems: [
        { id: 1, value: 'Col 1', isChecked: true },
        { id: 2, value: 'Col 2', isChecked: true },
        { id: 3, value: 'Col 3', isChecked: true },
        { id: 4, value: 'Col 4', isChecked: true },
        { id: 5, value: 'Col 5', isChecked: true },
        { id: 6, value: 'Col 6', isChecked: true },
        { id: 7, value: 'Col 7', isChecked: true },
        { id: 8, value: 'Col 8', isChecked: true },
        { id: 9, value: 'Col 9', isChecked: true },
        { id: 10, value: 'Col 10', isChecked: true },
      ],
    };
    this.handleFilterClickinv = this.handleFilterClickinv.bind(this);
    this.handleCustClickinv = this.handleCustClickinv.bind(this);
  }

  getTopBar() {
    return (
      <div className='top-bar-div'>
        <div className='heading-div'>Dashboard</div>
      </div>);
  }

  getFilterBar() {
    const searchIconImg = (<img src={searchIcon} alt="" />);
    if(this.state.isFiltered) table = this.state.filteredTableData;
    if(this.state.isSearched) table = this.state.searchedTableData;
    return (
      <div className='table-header-div' >
        <div className="filter-container-div">
        </div>
        <div className='search-enquiry-div'>
          <div className="search-container">
            <div className="search-input-container-div">
              <InputComponent
                height="41px"
                width="280px"
                inputClassName="order-filter-input"
                placeholder='Search'
                type="text"
                value={this.state.searchText}
                icon={searchIconImg}
                onChange={this.onSearch}
              />
            </div>
          </div>
        </div>
        <div className="filter-icon-div-main">
          <div className="custom-icon-div" onClick={() => { this.handleCustClickinv(); }}>
            <div className='customize-view-inventory'>Customized View </div>
          </div>
        </div>
      </div>);
  }

  getColumns() {
    const columns = [
        {
          id: "col16",
          Header: () => {
            return (
              <div>
                <div className="col1-heading">Col 1</div>
                <div className="col6-heading">Col 6</div>
              </div>
            );
          },
          accessor: d => {
            return (
              <div>
                <div className="col1">{d.firstName}</div>
                <div className="col6">{d.lastName}</div>
              </div>
            );
          },
          width: 200
        },
        {
          id: "col27",
          Header: () => {
            return (
              <div>
                <div className="col2-heading">Col 2</div>
                <div className="col7-heading">Col 7</div>
              </div>
            );
          },
          accessor: d => {
            return (
              <div>
                <div className="col2">{d.firstName}</div>
                <div className="col7">{d.lastName}</div>
              </div>
            );
          },
          width: 200
        },
        {
          id: "col38",
          Header: () => {
            return (
              <div>
                <div className="col3-heading">Col 3</div>
                <div className="col8-heading">Col 8</div>
              </div>
            );
          },
          accessor: d => {
            return (
              <div>
                <div className="col3">{d.firstName}</div>
                <div className="col8">{d.lastName}</div>
              </div>
            );
          },
          width: 200
        },
        {
          id: "col49",
          Header: () => {
            return (
              <div>
                <div className="col4-heading">Col 4</div>
                <div className="col9-heading">Col 9</div>
              </div>
            );
          },
          accessor: d => {
            return (
              <div>
                <div className="col4">{d.firstName}</div>
                <div className="col9">{d.lastName}</div>
              </div>
            );
          },
          width: 200
        },
        {
          id: "col510",
          Header: () => {
            return (
              <div>
                <div className="col5-heading">Col 5</div>
                <div className="col10-heading">Col 10</div>
              </div>
            );
          },
          accessor: d => {
            return (
              <div>
                <div className="col5">{d.firstName}</div>
                <div className="col10">{d.lastName}</div>
              </div>
            );
          },
          width: 200
        },
        {
          id: "col11",
          Header: "Col 11",
          columns: [
            {
              id: "scol11a",
              Header: "Sub Col 11a",
              accessor: d => {
                return d.firstName;
              },
              width: 80
            },
            {
              id: "scol11b",
              Header: "Sub Col 11b",
              accessor: d => {
                return d.firstName;
              },
              width: 80
            },
            {
              id: "scol11c",
              Header: "Sub Col 11c",
              accessor: d => {
                return d.firstName;
              },
              width: 80
            },
            {
              id: "scol11d",
              Header: "Sub Col 11d",
              accessor: d => {
                return d.firstName;
              },
              width: 80
            }
          ]
        },
        {
          id: "col12",
          Header: "Col 12",
          columns: [
            {
              id: "scol12a",
              Header: "Sub Col 12",
              accessor: d => {
                return d.firstName;
              },
              width: 80
            }
          ]
        },
        {
          id: "col13",
          Header: "Col 13",
          columns: [
            {
              id: "scol13a",
              Header: "Sub Col 13a",
              accessor: d => {
                return d.firstName;
              },
              width: 80
            },
            {
              id: "scol13b",
              Header: "Sub Col 13b",
              accessor: d => {
                return d.firstName;
              },
              width: 80
            },
            {
              id: "scol13c",
              Header: "Sub Col 13c",
              accessor: d => {
                return d.firstName;
              },
              width: 80
            },
            {
              id: "scol13d",
              Header: "Sub Col 13d",
              accessor: d => {
                return d.firstName;
              },
              width: 80
            }
          ]
        }
      ];

    // if(this.state.isDisabled) {
    //   columns.splice(0, 1);
    //   columns.splice(columns.length - 1, 1);
    // }
    return columns;
  }

  /*  function (item)*/

  getCheckBox(item) {
    return (
      <div>
        <input
          value={item.id}
          type='checkbox'
          checked={item.isChecked}
          onClick={(e) => { this.handleCheckChildElement(e); }}
        />
        {item.value}
      </div>);
  }

  handleCheckChildElement(event) {
    const { items } = this.state.filterItems;
    for (let i = 0; i < items.length; i = i + 1) {
      if(items[i].id === +event.target.value) {
        items[i].isChecked = !items[i].isChecked;
        break;
      }
    }
    this.setState({ filterItems: items });
    console.log('handleCheckChildElement : > Items : ' + JSON.stringify(filterItems));
  }

  handleFilterClickinv() {
    if(this.state.isCustomizedOpen) {
      this.setState({ isCustomizedOpen: false });
    }
    const currentState = this.state.isFilterOpen;
    this.setState({ isFilterOpen: !currentState });
  }

  handleCustClickinv() {
    if(this.state.isFilterOpen) {
      this.setState({ isFilterOpen: false });
    }
    const currentState = this.state.isCustomizedOpen;
    this.setState({ isCustomizedOpen: !currentState });
  }

  resetFilter() {
    const { items } = this.state.filterItems;
    console.log("In resetFilter this.state.filterItems : " + JSON.stringify(this.state.filterItems));
    console.log("In resetFilter : " + items);
    for (let i = 0; i < items.length; i = i + 1) {
      items[i].isChecked = true;
    }
    this.setState({ filterItems: items });
    console.log('Reset filter : > Items : ' + JSON.stringify(filterItems));
  }

  render() {
    const { data } = this.state;
    return (
      <div className='dashboard-body-container'>
        <div className='hide'> {this.state.activeStepId}</div>
        {this.getTopBar()}
        {this.state.isCustomizedOpen &&
          <CustomizedView
            // items={filterItems}
            getCheckBox={(item) => { this.getCheckBox(item); }}
            // handleCheckChildElement={(event) => { this.handleCheckChildElement(event); }}
            resetFilter={this.resetFilter()}
          />}
        <div className='whiteBackground'>
          {this.getFilterBar()}
          <div>
            {this.state.isLoading &&
            <LoadingComponent />
          }
          </div>
          <div>
            <ReactTable
              data={data}
              columns={this.getColumns()}
              showPagination
              defaultPageSize={10}
            />
          </div>
        </div>
      </div>
    );
  }
}

Dashboard.propTypes = {
};

function mapStateToProps(state) {
  return {
    auth: state.auth
  };
}

export default connect(mapStateToProps)(Dashboard);

這是我的子組件-在我的子頁面(顯示復選框的頁面)中,我有4個主要功能-getCheckbox-創建復選框,handlecheckchild-處理檢查取消選中事件,resetFilter和applyFilter。 我還沒有完成applyFilter的代碼。

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { ActionCreators } from '../../../actions';
import ButtonComponent from '../../common/button/ButtonComponent';

class CustomizedView extends Component {
  constructor(props) {
    super(props);
    this.state = {
    };
  }

  render() {
    const { items } = this.state;
    return (
      <div className='DashboardFilter-container-custom' >
        <div className='bottomBar'>
          <ButtonComponent
            text='Apply'
            className='activeButton filterMargin-div'
            width='100'
            display='inline-block'
            // onClick={() => { this.props.applyFilter(); }}
          />
          <ButtonComponent
            text='Reset View'
            className='greyedButton clear-div-filter'
            width='100'
            display='block'
            marginTop='60'
            onClick={() => { this.props.resetFilter(); }}
          />
        </div>
        <div>
          <div className='column-points-text'>
            <span> Columns </span>
          </div>
          <div className="App">
            {items.map((item) => {
                return this.props.getCheckBox(item);
            })}
          </div>
        </div>
      </div>
    );
  }
}

CustomizedView.propTypes = {
  // items: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
  getCheckBox: PropTypes.func.isRequired,
  // handleCheckChildElement: PropTypes.func.isRequired,
  resetFilter: PropTypes.func.isRequired
};

CustomizedView.defaultProps = {
};

function mapStateToProps(state) {
  return {
    auth: state.auth
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators(ActionCreators, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(CustomizedView);

我已經編寫了所有主要功能(用於父級子頁面中的操作,並將這些功能作為道具傳遞-從父頁面到子頁面的getCheckBox和resetFilter。

我的父頁面的這一行出現錯誤-無法讀取未定義的屬性“ length”

for (let i = 0; i < items.length; i = i + 1) {

我基本上是React的初學者。 因此,請幫助我了解導致錯誤的原因。

還告訴我是否可以在父頁面中編寫所有子功能?

編輯1-根據Code Maniac的回答

我將父代碼更改為

handleCheckChildElement(event) {
    const { filterItems } = this.state;
    for (let i = 0; i < filterItems.length; i = i + 1) {
      if(filterItems[i].id === +event.target.value) {
        filterItems[i].isChecked = !filterItems[i].isChecked;
        break;
      }
    }
    this.setState({ filterItems });
    console.log('handleCheckChildElement : > Items : ' + JSON.stringify(filterItems));
  }

  resetFilter() {
    const { filterItems } = this.state;
    for (let i = 0; i < filterItems.length; i = i + 1) {
      filterItems[i].isChecked = true;
    }
    this.setState({ filterItems });
    console.log('Reset filter : > Items : ' + JSON.stringify(filterItems));
  }

我現在遇到錯誤-道具resetFilterCustomizedView標記為必需,但其值undefined

我在無限循環中收到錯誤和警告。

編輯2-如果像這樣更改我的代碼

handleCheckChildElement(event) {
    const { items } = this.state;
    for (let i = 0; i < items.length; i = i + 1) {
      if(items[i].id === +event.target.value) {
        items[i].isChecked = !items[i].isChecked;
        break;
      }
    }
    this.setState({ filterItems: items });
    console.log('handleCheckChildElement : > Items : ' + JSON.stringify(filterItems));
  }

  resetFilter() {
    const { items } = this.state;
    for (let i = 0; i < items.length; i = i + 1) {
      items[i].isChecked = true;
    }
    this.setState({ filterItems: items });
    console.log('Reset filter : > Items : ' + JSON.stringify(filterItems));
  }

我正在檢查毛線生成錯誤-未使用狀態字段:“ filterItems” react / no-unused-state

好吧,您代碼中的問題在這里

const { items } = this.state.filterItems;

您正在嘗試在數組(fillterItems是一個數組)中找到鍵(item屬性),這就是為什么您不確定的原因。

這將與下面的示例相同。

 let a = [{v:1},{2:2}]; let {items} = a; console.log(items) 

而應該怎么做才能獲得正確的輸出。

const { filterItems } = this.state;

演示代碼

 let a = { items : [{v:1},{2:2}], itemstemp : "temp" } let {items} = a; console.log(items) 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM