I have a plain HTML page (part of a non-React application) with some text representing simple mathematical calculations. There are <span>
elements containing the formulae, and next to them <span>
elements with the calculations inside. Each span is represented with a generic class, either formula
or calculation
and also a specific class, such as formula-1
and calculation-1
. Note that the number in the classes will always be the same for associated formulae and calculations. These calculations are also dynamic in number; there could be 1 on a page or 30.
I'm using a React component to replace the calculation
spans with button
elements, and when a button is clicked it re-renders to show the calculation value. Some sample HTML and the JS are show below.
This solution works, but my issue is that it feels dirty. I'm quite new to React and JavaScript isn't my primary language, but it seems to me like each calculation element should be represented by an instance of the component, rather than a single component looping through all of the calculations on a page and rendering each.
So my question is: is the below working solution incorrect in terms of how React should be used, and if so, what's the generally accepted correct manner of doing this?
<span class="formula formula-1" data-calculation="4">2 + 2</span> = <span class="calculation calculation-1>4</span>
<span class="formula formula-2" data-calculation="6">2 + 4</span> = <span class="calculation calculation-2>6</span>
<span class="formula formula-3" data-calculation="22">2 + 20</span> = <span class="calculation calculation-3>22</span>
I'm created a React component that replaces the
import React, {Component} from "react";
import ReactDOM from "react-dom";
class Calculate extends Component {
constructor() {
super();
this.viewSolution = this.viewSolution.bind(this);
this.state = {
calculations: []
};
let formula_elements = document.getElementsByClassName('formula');
for (var i = 0; i < formula_elements.length; i++) {
this.state.calculations[i] = formula_elements[i].getAttribute('data-calculation');
}
}
viewSolution(event) {
this.setState({
clicked: true
});
}
render() {
if (this.state.clicked === true) {
return (
<span>{this.state.calculations[this.props.index]}</span>
);
}
return (
<button className="btn" onClick={this.viewSolution}>View solution</button>
);
}
}
export default Calculate;
const calculation_elements = document.getElementsByClassName('calculation');
for (var i = 0; i < calculation_elements.length; i++) {
ReactDOM.render(<Calculate index={i}/>, calculation_elements[i]);
}