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 { div.controller {
margin : 10px; padding-left : 240px;
padding : 10px;
border : solid thin #AAA;
} }
div.controller button {
margin : 0px 10px;
}
div.controls {
margin : 10px;
padding : 10px;
border : solid thin #AAA;
}
div.controls button {
margin : 0px 10px;
}
div.personListing { div.personListing {
border : dashed thin black ; border : dashed thin black ;
padding : 10px; 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,17 +2,13 @@ import { useState, useEffect, useRef } from 'react'; ...@@ -2,17 +2,13 @@ import { useState, useEffect, useRef } from 'react';
import '../assets/style/person.css'; 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( () => { useEffect( () => {
if (started) { if (started) {
timer.current = setInterval( () => { timer.current = setInterval( () => incrementAge( id ), delay);
setCurrentAge( previousCurrentAge => previousCurrentAge + 1 );
console.log('timer is running');
}, delay);
} }
return () => clearInterval( timer.current ); return () => clearInterval( timer.current );
}, [started, delay] ); }, [started, delay] );
...@@ -20,7 +16,7 @@ useEffect( () => { ...@@ -20,7 +16,7 @@ useEffect( () => {
return ( return (
<div className="person">Here is : <div className="person">Here is :
<div>name : <span>{ name }</span> </div> <div>name : <span>{ name }</span> </div>
<div>age : <span>{ currentAge } </span> </div> <div>age : <span>{ age } </span> </div>
</div> </div>
); );
} }
......
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { mockFetch } from '../util/mockAPI.js';
import '../assets/style/personListing.css'; import '../assets/style/personListing.css';
...@@ -8,18 +8,7 @@ import Person from './person.component.jsx'; ...@@ -8,18 +8,7 @@ import Person from './person.component.jsx';
const PersonListing = props => { const PersonListing = props => {
const { started, delay } = props; const { persons, incrementAge, 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 personComponents = persons.map(person => <Person const personComponents = persons.map(person => <Person
{...person} {...person}
......
...@@ -5,11 +5,14 @@ import '../assets/style/displayController.css'; ...@@ -5,11 +5,14 @@ import '../assets/style/displayController.css';
import PersonListing from './personListing.component.jsx'; import PersonListing from './personListing.component.jsx';
import PersonListingControls from './personListingControls.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 [ closed, setClosed ] = useState(false);
const [ started, setStarted ] = useState(false); const [ started, setStarted ] = useState(false);
const [ delay, setDelay ] = useState(initialDelay) const [ delay, setDelay ] = useState(INITIAL_DELAY);
const startStop = () => setStarted( previousStarted => ! previousStarted); const startStop = () => setStarted( previousStarted => ! previousStarted);
const closeComponent = () => { const closeComponent = () => {
...@@ -24,6 +27,7 @@ const PersonListingController = ({ initialDelay = 250 }) => { ...@@ -24,6 +27,7 @@ const PersonListingController = ({ initialDelay = 250 }) => {
return null; return null;
else else
return (<PersonListing return (<PersonListing
{ ...props }
delay={delay} delay={delay}
started={started} started={started}
/>); />);
...@@ -40,7 +44,7 @@ const PersonListingController = ({ initialDelay = 250 }) => { ...@@ -40,7 +44,7 @@ const PersonListingController = ({ initialDelay = 250 }) => {
} }
return ( return (
<div> <div className="controller">
{ buildListingControls() } { buildListingControls() }
{ buildPersonListing() } { buildPersonListing() }
</div> </div>
......
import '../assets/style/displayController.css'; import '../assets/style/personControls.css';
import DelayButton from './delayButton.component.jsx'; import DelayButton from './delayButton.component.jsx';
...@@ -13,7 +13,7 @@ const PersonListingControls = ( { started, closed, changeDelay, closeAction, sta ...@@ -13,7 +13,7 @@ const PersonListingControls = ( { started, closed, changeDelay, closeAction, sta
return( return(
<div className = 'controller'> <div className = 'controls'>
<button onClick= { startStop }> <button onClick= { startStop }>
{ started ? 'Stop' : 'Start' } { started ? 'Stop' : 'Start' }
</button> </button>
......
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 { createRoot } from 'react-dom/client';
import PersonListingController from '../components/personListingController.component.jsx'; import App from '../components/app.component.jsx';
import { StrictMode } from 'react';
const bootstrapReact = () => { const bootstrapReact = () => {
const root = createRoot(document.getElementById('insertReactHere')); const root = createRoot(document.getElementById('insertReactHere'));
const component = <PersonListingController />; const component = <App />;
root.render(component); root.render(component);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment