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;
}