React Base Fiddle (JSX)
Starting point for creating JSFiddles with React.
HTML
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
CSS
.green_button {
background-color: #4CAF50; /* Green */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
cursor: default;
font-size: 16px;
}
.blue_button {
background-color: #008CBA; /* Green */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
cursor: default;
font-size: 16px;
}
React
class Hello extends React.Component {
state = {a: 1, b: 1, c: 1};
someEffect = effect((a) => {
console.log('I am running because my param has been changed!', a);
this.setState({c: this.state.c +1});
});
render() {
this.someEffect(this.state.a);
return (
<div>
<p>Click on the green button and see how the effect is being triggered (check the logs). click on the blue button to update a non relevant param and see how the effect is not triggered</p>
<p>a: {this.state.a}, b: {this.state.b} c: {this.state.c}</p>
<div className="green_button" onClick={() => this.setState({a: this.state.a + 1})}>click to update a</div>
<div className="blue_button" onClick={() => this.setState({b: this.state.b + 1})}>click to update b</div>
</div>
);
}
}
ReactDOM.render(
<Hello name="World" />,
document.getElementById('container')
);
type ClearEffectFN = (() => void) | undefined;
type EffectFN = (...args: any[]) => ClearEffectFN;
function effect(fn: EffectFN) {
let prevParams: any[] | undefined = undefined;
let clearFN: ClearEffectFN = undefined;
return (...params: any[]) => {
if (prevParams === undefined || isChanged(prevParams, params)) {
if (typeof clearFN === 'function') {
clearFN();
}
clearFN = fn(...params);
}
prevParams = params;
}
}
function isChanged(prevParams: any[], currentParams: any[]) {
let isChanged = false;
prevParams.forEach((param, index) => {
if (param !== currentParams[index]) {
isChanged = true;
}
});
return isChanged;
}