Skip to content
Snippets Groups Projects
Commit ed1e5e61 authored by Jean-Christophe's avatar Jean-Christophe
Browse files

reafctorisation : remonter l'état

parent 33aff202
No related branches found
No related tags found
No related merge requests found
Showing
with 183 additions and 64 deletions
div#app {
position : relative;
min-height: 200px;
}
span.label, span.value {
padding : 8px;
}
span.value {
font-weight : bold;
}
div.controller {
margin : 10px;
padding : 10px;
border : solid thin #AAA;
padding-left : 240px;
}
div.controller button {
margin : 0px 10px;
}
div.person {
padding: 4px 8px;
margin: 10px;
background-color: rgba(128, 128, 255, 0.7);
color: white;
font-size: medium;
padding : 4px 8px;
margin : 10px;
background-color : rgba(128,128,255, 0.7);
color : white;
font-size : medium;
}
div.person>div {
margin: 3px 15px;
div.person > div {
margin : 3px 15px;
}
div.person span {
color: black;
}
\ No newline at end of file
color : black;
}
div.controls {
margin : 10px;
padding : 10px;
border : solid thin #AAA;
}
div.controls button {
margin : 0px 10px;
}
div.personListing {
border : dashed thin black ;
padding : 10px;
margin : 5px;
}
div.data {
margin : 10px;
border : solid 2px rgb(60,60,255);
background-color : white;
font-size : 16px;
position : absolute;
left : 0px;
top : 30px;
}
div.data div {
padding : 4px 0px;
border : solid thin #CCC;
}
div.controller {
padding-left : 240px;
}
.rating {
margin : 10px;
font-size : x-large;
}
.rating img {
width : 48px;
vertical-align : middle;
}
import { useState, useEffect } from 'react';
import '../assets/style/app.css';
import PersonListingController from './personListingController.component.jsx';
import PersonListingData from './personListingData.component.jsx';
import { mockFetch } from '../util/mockAPI.js';
const App = () => {
const [persons, setPersons ] = useState([]);
const fetchData = async () => {
const data = await mockFetch('http://source.of.data/persons',10);
setPersons( data );
}
useEffect( () => {
fetchData();
}, []);
/* increment age of person with given id, state is updated */
const incrementAge = (personId) => {
setPersons ( previousPersons => {
const olderPerson = previousPersons.find( person => person.id === personId );
olderPerson.age = olderPerson.age + 1;
return [...previousPersons];
});
}
return(
<div id="app">
<PersonListingController
persons = { persons }
incrementAge = { incrementAge }
/>
<PersonListingData
persons = { persons }
/>
</div>
);
}
export default App;
\ No newline at end of file
import '../assets/style/data.css';
const Data = ( { label, value }) => {
return(
<div>
<span className= "label"> { label } </span>
:
<span className= "value"> { value } </span>
</div>
);
}
export default Data;
\ No newline at end of file
......@@ -2,26 +2,22 @@ import { useState, useEffect, useRef } from 'react';
import '../assets/style/person.css';
const Person = ( { name = 'Anonymous', age, started, delay } ) => {
const Person = ( { name = 'Anonymous', age, id, started, delay, incrementAge } ) => {
const [ currentAge, setCurrentAge ] = useState(age);
const timer = useRef( undefined );
const timer = useRef( undefined );
useEffect( () => {
if (started) {
timer.current = setInterval( () => {
setCurrentAge( previousCurrentAge => previousCurrentAge + 1 );
console.log('timer is running');
}, delay);
}
return () => clearInterval( timer.current );
}, [started, delay] );
useEffect( () => {
if (started) {
timer.current = setInterval( () => incrementAge( id ), delay);
}
return () => clearInterval( timer.current );
}, [started, delay] );
return (
<div className="person">Here is :
<div>name : <span>{ name }</span> </div>
<div>age : <span>{ currentAge } </span> </div>
</div>
);
return (
<div className="person">Here is :
<div>name : <span>{ name }</span> </div>
<div>age : <span>{ age } </span> </div>
</div>
);
}
export default Person;
import { useState, useEffect } from 'react';
import { mockFetch } from '../util/mockAPI.js';
import '../assets/style/personListing.css';
......@@ -8,18 +8,7 @@ import Person from './person.component.jsx';
const PersonListing = props => {
const { started, delay } = props;
const [persons, setPersons ] = useState([]);
const fetchData = async () => {
const data = await mockFetch('http://source.of.data/persons',10);
setPersons( data );
}
useEffect( () => {
fetchData();
}, []);
const { persons, incrementAge, started, delay } = props;
const personComponents = persons.map(person => <Person
{...person}
......
......@@ -5,11 +5,14 @@ import '../assets/style/displayController.css';
import PersonListing from './personListing.component.jsx';
import PersonListingControls from './personListingControls.component.jsx';
const PersonListingController = ({ initialDelay = 250 }) => {
const INITIAL_DELAY= 1000;
const PersonListingController = ( props ) => {
const { persons, incrementAge } = props;
const [ closed, setClosed ] = useState(false);
const [ started, setStarted ] = useState(false);
const [ delay, setDelay ] = useState(initialDelay)
const [ delay, setDelay ] = useState(INITIAL_DELAY);
const startStop = () => setStarted( previousStarted => ! previousStarted);
const closeComponent = () => {
......@@ -24,6 +27,7 @@ const PersonListingController = ({ initialDelay = 250 }) => {
return null;
else
return (<PersonListing
{ ...props }
delay={delay}
started={started}
/>);
......@@ -40,9 +44,9 @@ const PersonListingController = ({ initialDelay = 250 }) => {
}
return (
<div>
{buildListingControls()}
{buildPersonListing()}
<div className="controller">
{ buildListingControls() }
{ buildPersonListing() }
</div>
);
......
import '../assets/style/displayController.css';
import '../assets/style/personControls.css';
import DelayButton from './delayButton.component.jsx';
......@@ -13,14 +13,14 @@ const PersonListingControls = ( { started, closed, changeDelay, closeAction, sta
return(
<div className = 'controller'>
<button onClick= { startStop }>
{ started ? 'Stop' : 'Start' }
</button>
{ buildDelayButtons() }
<button onClick= { closeAction }>
{ closed ? 'Open' : 'Close' }
</button>
<div className = 'controls'>
<button onClick= { startStop }>
{ started ? 'Stop' : 'Start' }
</button>
{ buildDelayButtons() }
<button onClick= { closeAction }>
{ closed ? 'Open' : 'Close' }
</button>
</div>
);
}
......
import '../assets/style/personListingData.css';
import Data from './data.component.jsx';
const PersonListingData = ( { persons } ) => {
const nbPersonsOlderThan = minAge => {
return persons.filter( person => person.age > minAge ).length ;
}
const ageList = () => {
return persons.map( person => person.age );
}
return(
<div className="data">
<Data label="nb personnes" value={ persons.length } />
<Data label="âge &gt; 18" value={ nbPersonsOlderThan(18) } />
<Data label="âge &gt; 50" value={ nbPersonsOlderThan(50) } />
<Data label="âge du plus jeune&nbsp;" value={ Math.min(...ageList()) } />
<Data label="âge du plus vieux&nbsp;" value={ Math.max(...ageList()) } />
</div>
);
}
export default PersonListingData;
\ No newline at end of file
import { createRoot } from 'react-dom/client';
import PersonListingController from '../components/personListingController.component.jsx';
import { StrictMode } from 'react';
import App from '../components/app.component.jsx';
const bootstrapReact = () => {
const root = createRoot(document.getElementById('insertReactHere'));
const component = <PersonListingController />;
const component = <App />;
root.render(component);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment