<div id="errors" style="
  background: #c00;
  color: #fff;
  display: none;
  margin: -20px -20px 20px;
  padding: 20px;
  white-space: pre-wrap;
"></div>
<div id="root"></div>
<script>
window.addEventListener('mousedown', function(e) {
  document.body.classList.add('mouse-navigation');
  document.body.classList.remove('kbd-navigation');
});
window.addEventListener('keydown', function(e) {
  if (e.keyCode === 9) {
    document.body.classList.add('kbd-navigation');
    document.body.classList.remove('mouse-navigation');
  }
});
window.addEventListener('click', function(e) {
  if (e.target.tagName === 'A' && e.target.getAttribute('href') === '#') {
    e.preventDefault();
  }
});
window.onerror = function(message, source, line, col, error) {
  var text = error ? error.stack || error : message + ' (at ' + source + ':' + line + ':' + col + ')';
  errors.textContent += text + '\n';
  errors.style.display = '';
};
console.error = (function(old) {
  return function error() {
    errors.textContent += Array.prototype.slice.call(arguments).join(' ') + '\n';
    errors.style.display = '';
    old.apply(this, arguments);
  }
})(console.error);
</script>
body {
  font: 14px "Century Gothic", Futura, sans-serif;
  margin: 20px;
  background-image:url('https://www.yioka.eu/css/images/background.png');
}
h1{color:#CDBFAC}
h3{
  padding-left:1em;
  color:#333;
}
.row{width:100%; float:left;}
.btn{
  background:#fff;
  color:#FF6600;
  font-weight:bold;
  padding:0.5em 1em;
  border-radius:5px;
  border:1px solid #FF6600;
  margin:2em 0;
}
label{
  width:100%;
}
input{
  margin:0.5em;
  padding:0.5em ;
  border-radius: 5px;
  border:1px solid #cdcdcd;
  max-width:50px;
  
}
.person{
  min-width:70px;
  margin:0.5em;
  padding:0.5em;
  float:left;
  border-radius:10px;
  border:1px solid #999;
  background:#fff;
  box-shadow: 0 0 10px #999;
}
.people{
  display: flex;
  flex-wrap: wrap;
}
.finalPercent{
  color:#FF6600;
  font-weight:bold;
  font-size:1.2em;
  border:1px solid #ffc096;
  padding: 0.3em 0.8em;
  border-radius:5px;
  background: rgba(255,255,255,0.5);
}
let  personID = 0;
class Person extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      heirs : 0,
      percent : this.props.percent
    };
  }
  addPerson(x){
    let nextGen = parseInt(this.props.generation) + 1;
    let nextPerson = this.props.number+ "_" + x;
    return(<Person key={x} number={nextPerson} generation={nextGen} percent={getPercentage(nextPerson)}/>);
  }
  handleChange(e) {
    updatePercentage(this.props.number,e)
    this.setState({percent: getPercentage(this.props.number)});
  }
  render(){
    let heirs = []
    for(let i=1;i<=this.state.heirs;i++){
      heirs.push(i)
    }
    let gen = this.props.number;
    return(
      <div className='person'>
        <div className='row'>
          <h3>Άτομο n({gen})</h3>
        </div>
        <div className='row'>
          <input type="text" defaultValue={this.props.percent}  placeholder='Ποσοστό' onChange={(e) => this.handleChange(e.target.value)}  />     <span className='finalPercent'>{this.props.percent}</span>
        </div>
        <div className='row'>
          <input type="number" name={"heirs_" + this.props.number} onBlur={(e) => this.setState({heirs:e.target.value})} placeholder='heirs'/>
        </div>
        <div className='row'>
          {
            heirs.map ( (n) => {
                return this.addPerson(n)
            })

        }
        </div>
      </div>
    );
  }
}
function updatePercentage(key,value){
  if(typeof this.state.percentages[key] != "undefined"){
    this.state.percentages[key] = value;    
  }else{
    this.setState({percentages: Object.assign( {}, this.state.percentages, { [key] : value })} );    
  }
    console.log(this.state.percentages);
}
function getPercentage(key){
  if(typeof this.state.percentages[key] != "undefined"){
    return this.state.percentages[key];    
  }else{
    return '0';  
  }
  
}
class App extends React.Component {
  constructor(props){
    super(props);
    this.state =  {
      percentages : {1:"1/1"}
    };
    updatePercentage = updatePercentage.bind(this); 
    getPercentage = getPercentage.bind(this);
    this.calculate = this.calculate.bind(this);
  }
  calculate(){
    let toLCM = new Array();
    let gcd = (a, b) => a ? gcd(b % a, a) : b;
    let lcm = (a, b) => a * b / gcd(a, b);
    Object.keys(this.state.percentages).forEach(key => {
        let splitted = this.state.percentages[key].split("/"); 
        toLCM.push(splitted[1]);   // the value of the current key.
    });
    let newLCM = toLCM.reduce(lcm);
    let key = '';
    let percent = this.state.percentages;
    Object.keys(this.state.percentages).forEach(key => {
        let splitted = this.state.percentages[key].split("/"); 
        let toMulti = newLCM/math.number(splitted[1]);
        let newValeu = math.number(splitted[0])*toMulti+'/'+math.number(splitted[1])*toMulti;
        percent[key] = newValeu;
    });
    this.setState({percentages : percent}); 
    console.log(this.state.percentages);
  } 
  render() {
   
    
    return (
      <div className="generation">
        <h1>Κληρονομιά μεριδίων</h1>
        <div className='people'>
          <Person generation='1' number='1' percent={this.state.percentages[1]}/>
        </div>
        <div className='row'>
          <button onClick={this.calculate} className='btn'>Υπολογισμός</button>
        </div>
      </div>
    );
  }
}

// ========================================

ReactDOM.render(
  <App />,
  document.getElementById('root')
);
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://unpkg.com/react@16/umd/react.development.js
  2. https://unpkg.com/react-dom@16/umd/react-dom.development.js
  3. https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.7.0/math.min.js
  4. https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js