2

I learn React and read code and now I see this Eslint warning

(props(

I refactor the code like this: removing props

constructor() {
    super();
    this.state = this.parse();
}

Now Eslint is happy but the code breaks because of probably props cant be used in the this.parse();

How is this suppose to work?

Completet code:

// Copyright (c) 2017 PlanGrid, Inc.

import React, { Component } from 'react';
import XLSX from 'xlsx';

import CsvViewer from './csv-viewer';
import WithFetching from '../file-viewer/fetch-wrapper';

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

    parse() {
        const { data } = this.props;
        const dataArr = new Uint8Array(data);
        const arr = [];

        for (let i = 0; i !== dataArr.length; i += 1) {
            arr.push(String.fromCharCode(dataArr[i]));
        }

        const workbook = XLSX.read(arr.join(''), { type: 'binary' });
        const names = Object.keys(workbook.Sheets);
        const sheets = names.map(name => XLSX.utils.sheet_to_csv(workbook.Sheets[name]));

        return { sheets, names, curSheetIndex: 0 };
    }

    renderSheetNames(names) {
        const sheets = names.map((name, index) => (
            <input
                key={name}
                type="button"
                value={name}
                onClick={() => {
                    this.setState({ curSheetIndex: index });
                }}
            />
        ));

        return <div className="sheet-names">{sheets}</div>;
    }

    renderSheetData(sheet) {
        const csvProps = { ...this.props, data: sheet };
        return <CsvViewer {...csvProps} />;
    }

    render() {
        const { sheets, names, curSheetIndex } = this.state;
        return (
            <div className="spreadsheet-viewer">
                {this.renderSheetNames(names)}
                {this.renderSheetData(sheets[curSheetIndex || 0])}
            </div>
        );
    }
}

export default WithFetching(XlxsViewer);
Kid
  • 1,869
  • 3
  • 19
  • 48
  • How does the code "break" if you don't use `props` argument? What specific issue? Also, looks like the warning is technically incorrect, there's posts about it like this one: https://stackoverflow.com/questions/63856962/understanding-why-super-is-deprecated-in-a-react-class-component/63857001#63857001 – Jayce444 Sep 26 '20 at 11:06
  • It breaks here `const { data } = this.props;` The `data` does not exist – Kid Sep 26 '20 at 11:08
  • To be honest, it looks like this is a TypeScript bug (see a convo here: https://github.com/microsoft/TypeScript/issues/40511) so you can safely ignore when it complains about `super(props)`. Microsoft should fix it and then you can just update your dependencies. For now, just ignore. You're right, you could pass through the props to the `parse` argument to if you like. It's a bit weird but should technically be functional – Jayce444 Sep 26 '20 at 11:17

2 Answers2

1

we use super(props) in order to access props in constructor. you are not using props in constructor thats why eslint is giving error

so in order to remove error from eslint and code building

 constructor() {
        this.state = this.parse();
    }

use arrow function for binding

parse=()=>{
//code
}
Aurangzaib Rana
  • 4,028
  • 1
  • 14
  • 23
1

An advice, move the parse() part to componentDidMount(). the constructor should be used in two cases only and shouldn't have any side-effects:

  • Initializing local state by assigning an object to this.state.
  • Binding event handler methods to an instance.

Also, not calling super(props) will result in you not being able to have the actual values inside this.props as it will be undefined.

A refactor to this code using this.setState() would look like:

import React, { Component } from "react";
import XLSX from "xlsx";

import CsvViewer from "./csv-viewer";
import WithFetching from "../file-viewer/fetch-wrapper";

class XlxsViewer extends Component {
  componentDidMount() {
    this.parse();
  }

  parse() {
    const { data } = this.props;
    const dataArr = new Uint8Array(data);
    const arr = [];

    for (let i = 0; i !== dataArr.length; i += 1) {
      arr.push(String.fromCharCode(dataArr[i]));
    }

    const workbook = XLSX.read(arr.join(""), { type: "binary" });
    const names = Object.keys(workbook.Sheets);
    const sheets = names.map((name) =>
      XLSX.utils.sheet_to_csv(workbook.Sheets[name])
    );

    this.setState({ sheets, names, curSheetIndex: 0 });
  }
  ...
}

export default WithFetching(XlxsViewer);
Osama Sayed
  • 1,993
  • 15
  • 15