philnoug@home:~$

Premiers pas en ReactJS

Premiers pas en React avec comme excervice imposé la réalisation d’une appli qui estime l’autonomie de la Renault ZOE à partir de 3 critères; la vitesse, la témpérature et le niveau de la batterie.

La logique est un peu la même qu’avec Angular, mais cette fois le couple Label et Select Range forme un composant Slider mais on utilise ici quelques concepts issus de la programmation fonctionnelle comme la dé claration d’un maximum de constantes ( const x = 1; ) et l’assignation de valeurs à une variable par déconstruction ( const {x,y} = this.props; ).

import React, { Component } from 'react';
import './App.css';

class App extends Component {
    constructor(props) {
        
        super(props);
        
        this.state = { 
            charge: 100, 
            speed: 50,   
            temp: 20,    
            kms: 380,  
        }  
        
        // on stocke dans des variables d'instance les états sinon 
        // le calcul se fait avec les valeurs avant le onChange !!     
        // https://medium.freecodecamp.org/functional-setstate-is-the-future-of-react-374f30401b6b       
        // Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.  
        this.charge = this.state.charge;
        this.speed  = this.state.speed;       
        this.temp   = this.state.temp;    
        
        // les valeurs clées
        this.consommations = { '50': 5.35, '60': 6.83, '70': 8.83, '80': 11.12, '90': 13.82, '100': 17.75, '110': 22.22, '120': 27.33, '130': 32.7 };      
        this.températures  = { '20': 0, '10': 2.5, '0': 5, '-10': 7.5, '-20': 10};    
        
        // on 'binde' la fonction qui se déclenchera sur le changement de valeur des controles 
        this.handleOnChange = this.handleOnChange.bind(this);      
    }

    handleOnChange(event) {    
        const key = String(event.target.id);    
        const value = event.target.value;         
        
        // Conserve la valeur du slider (charge/speed/temp)
        this[key] = value;      
        
        // Rafraichir l'affichage
        this.setState({ [key]: value });   
        
        // Rafraichir l'affichage  
        this.setState({ [key]: value });   

        // Recalculer l'estimation         
        this.calculate(this.charge, this.speed, this.temp);    
    }      

    calculate(_charge, _speed, _temp) {  
        // Calculer la puissance restante  
        const _puissance = 41; // Batterie ZOE 4.0 (41kW)      
        const _battery   = _puissance - (_puissance * (100 - _charge) / 100);      

        // Calculer la consommation        
        const _conso = this.consommations[_speed];   
        let _autonomie = _battery * (parseInt(_speed) / _conso);         

        // Calculer l'impact de la température ext.  
        const _impact = this.températures[_temp];    
        _autonomie  = _autonomie - (_autonomie * _impact / 100);         

        this.setState({ kms: _autonomie });
    }      

    render() {       
        const { charge, speed, temp, kms } = this.state;       
        return (       
            <div className="App">      
                <Slider 
                    id="charge"        
                    label="Batterie" unit="%" min="0" max="100"      
                    value={charge}     
                    onChange={this.handleOnChange}         
                />      

                <Slider 
                    id="speed"         
                    label="Vitesse" unit="km/h" min="50" max="130"   
                    value={speed}      
                    onChange={this.handleOnChange}         
                />      

                <Slider 
                    id="temp"
                    label="Température" unit="°" min="-20" max="20"  
                    value={temp}       
                    onChange={this.handleOnChange}         
                />   

                <div id="autonomie">Autonomie: { kms | 0 } kms</div>       
            </div> 
        );   
    }      
}        

// On crée un composant Slider pour éviter de se répéter.... 

class Slider extends Component {       
    render() {     
       const { id, label, unit, min, max, value, onChange } = this.props;       
       return (     
         <div>
            <span>{label}: {value}{unit}</span>  
            <input
                id   = { id }    
                min  = { min }   
                max  = { max }   
                value= { value } 
                onChange= { onChange }     
                type = "range"   
                step = "10"      
            />    
         </div>         
       ); 
    }    
}  

export default App;</pre>