Я использую библиотеку javascript JExcel с React. В документации описан подход с компонентами, но используется ReactDOM.findDOMNode()
, который, как мне кажется, устарел.
Я пытался переместить его в функциональный компонент, но, хотя он якобы работает, есть проблема, заключающаяся в том, что компонент React, использующий класс, повторно рендерится примерно 5 раз... и каждый повторный рендеринг заставляет элемент JExcel добавьте еще один лист!
Вот исходный пример кода:
import React from "react";
import ReactDOM from "react-dom";
import jexcel from "jexcel-pro";
import "./styles.css";
import "../node_modules/jexcel-pro/dist/jexcel.css";
class App extends React.Component {
constructor(props) {
super(props);
this.options = props.options;
}
componentDidMount = function() {
this.el = jexcel(ReactDOM.findDOMNode(this).children[0], this.options);
};
addRow = function() {
this.el.insertRow();
};
render() {
return (
<div>
<div />
<br />
<input
type="button"
value="Add new row"
onClick={() => this.addRow()}
/>
</div>
);
}
}
const options = {
data: [
[123, 412],
[null, 32, 43],
[null, null, 41, null, 54],
[null, 123, null, 64, 23],
[null, null, 41, 23, 123]
],
minDimensions: [5, 5],
freezeColumns: 2,
allowComments: true,
tableOverflow: true,
tabs: false,
allowCreateTabs: false,
tableWidth: "100%"
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App options={options} />, rootElement);
Вот моя обновленная версия в виде компонента <MyGrid />
:
import React, { useEffect, useRef, useState } from "react";
import ReactDOM from "react-dom";
import jexcel from "jexcel-pro";
import "./styles.css";
import "../node_modules/jexcel-pro/dist/jexcel.css";
function App(props) {
var options = {
data: [
[123, 412],
[null, 32, 43],
[null, null, 41, null, 54],
[null, 123, null, 64, 23],
[null, null, 41, 23, 123]
],
minDimensions: [5, 5],
freezeColumns: 2,
allowComments: true,
tableOverflow: true,
tabs: false,
allowCreateTabs: false,
tableWidth: "100%"
};
return <MyGrid options={options} />;
}
function MyGrid(props) {
const { options } = props;
const sheetRef = useRef(null);
const [mySheet, setMySheet] = useState(null);
useEffect(() => {
setMySheet(jexcel(sheetRef.current, options));
}, [options]);
function addRow() {
mySheet.insertRow();
}
return (
<div>
<div ref={sheetRef} />
<br />
<input type="button" value="Add new row" onClick={() => addRow()} />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Проблема в том, что данные поступают через выборку в родительском компоненте. Я подозреваю, что это связано с этим или, возможно, с моим плохим использованием useRef
. Есть ли лучший подход?