I learn React and read code and now I see this Eslint warning
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);
An advice, move the parse()
part to componentDidMount()
. the constructor should be used in two cases only and shouldn't have any side-effects:
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);