diff --git a/readme.md b/readme.md index 4307ee87a22aef78a7e822a88b9e104e14e3ef5e..7818c521861308e12f89a982150c1bbe6b8e783e 100644 --- a/readme.md +++ b/readme.md @@ -67,7 +67,8 @@ où `tag` peut prendre comme valeur : voir `/src/components/personListingControls.component.jsx` et `/src/components/personListingController.component.jsx` * `v6.2` : refactorisation des composants, on continue à "remonter l'état" voir `/src/components/app.jsx`, `/src/components/personListingData.jsx` - +* `v7` : exemple de composant avec des élément *non contrôlés* par *React* + voir `/src/components/addPerson.jsx` Faire ```git checkout main``` pour revenir à la version finale. diff --git a/src/assets/style/addPerson.css b/src/assets/style/addPerson.css new file mode 100644 index 0000000000000000000000000000000000000000..99f8954d2c2f97cc3148121b45143d9c3af4a3f4 --- /dev/null +++ b/src/assets/style/addPerson.css @@ -0,0 +1,9 @@ +div.addPerson { + padding : 4px; + margin : 5px auto 0px 20px; + border : solid thin #BBB; + text-align : center; +} +div.addPerson input { + margin : 0px 5px; +} diff --git a/src/components/addPerson.component.jsx b/src/components/addPerson.component.jsx new file mode 100644 index 0000000000000000000000000000000000000000..b7eac3aba6c26f4965003131964a37b3dbd85900 --- /dev/null +++ b/src/components/addPerson.component.jsx @@ -0,0 +1,42 @@ +import { useRef } from 'react'; + +import '../assets/style/addPerson.css'; + +const DEFAULT_NAME = 'Anonymous'; +const DEFAULT_AGE = 12; + +const AddPerson = ( { addPerson } ) => { + + const nameInputRef = useRef(null); + const ageInputRef = useRef(null); + + const handleClick = () => { + const person = { + name: nameInputRef.current.value || DEFAULT_NAME, + age: parseInt(ageInputRef.current.value) || DEFAULT_AGE + }; + addPerson(person); + clearFields(); + } + + const clearFields = () => { + nameInputRef.current.value = ''; + ageInputRef.current.value = ''; + } + + return ( + <div className="addPerson"> + <input + type="text" placeholder="Name" + ref={nameInputRef} + /> + <input + type="number" min="0" placeholder="Age" + ref={ageInputRef} + /> + <button onClick={handleClick}>Add</button> + </div> + ); +} + +export default AddPerson; \ No newline at end of file diff --git a/src/components/app.component.jsx b/src/components/app.component.jsx index 79920e62710427e05303f5f7a810f275ea6fbee5..ebf79f29a016d2ce5363eeb9fefa57d70cbf7c0f 100644 --- a/src/components/app.component.jsx +++ b/src/components/app.component.jsx @@ -9,37 +9,44 @@ import { mockFetch } from '../util/mockAPI.js'; const App = () => { - const [persons, setPersons ] = useState([]); + const [persons, setPersons ] = useState([]); - const fetchData = async () => { - const data = await mockFetch('http://source.of.data/persons',10); - setPersons( data ); - } + const fetchData = async () => { + const data = await mockFetch('http://source.of.data/persons',10); + setPersons( data ); + } - useEffect( () => { + 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> -); + }, []); + + /* 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]; + }); + } + + const addPerson = person => { + const newId = `A${persons.length + 1}`; + const newPerson = { ...person, id: newId }; + setPersons(previousPersons => [...previousPersons, newPerson] ); + } + + return( + <div id="app"> + <PersonListingController + persons = { persons } + incrementAge = { incrementAge } + addPerson = { addPerson } + /> + <PersonListingData + persons = { persons } + /> + </div> + ); } export default App; \ No newline at end of file diff --git a/src/components/personListingController.component.jsx b/src/components/personListingController.component.jsx index c4778555b3b40ff9ec78a8ff9b18621ee9311b1f..ef0c744624d439d918f4f42bf2c8ab68d81bbf4e 100644 --- a/src/components/personListingController.component.jsx +++ b/src/components/personListingController.component.jsx @@ -9,6 +9,8 @@ const INITIAL_DELAY= 1000; const PersonListingController = ( props ) => { + const { addPerson } = props; + const [ closed, setClosed ] = useState(false); const [ started, setStarted ] = useState(false); const [ delay, setDelay ] = useState(INITIAL_DELAY); @@ -40,7 +42,8 @@ const PersonListingController = ( props ) => { changeDelay={changeDelay} closeAction={closeComponent} startStop={startStop} - />); + addPerson={addPerson} + />); } return ( diff --git a/src/components/personListingControls.component.jsx b/src/components/personListingControls.component.jsx index f233637a65c62b8048e751c2d788d7c0f94c36b8..6157941fd801ad16097f5dcd45d9b6cc246e5d72 100644 --- a/src/components/personListingControls.component.jsx +++ b/src/components/personListingControls.component.jsx @@ -1,8 +1,9 @@ import '../assets/style/personControls.css'; import DelayButton from './delayButton.component.jsx'; +import AddPerson from './addPerson.component.jsx'; -const PersonListingControls = ( { started, closed, changeDelay, closeAction, startStop } ) => { +const PersonListingControls = ( { started, closed, changeDelay, closeAction, startStop, addPerson } ) => { const buildDelayButtons = () => { const delayButtons = [250,1000,3000].map ( delay => <DelayButton delay = { delay } @@ -21,6 +22,9 @@ const PersonListingControls = ( { started, closed, changeDelay, closeAction, sta <button onClick= { closeAction }> { closed ? 'Open' : 'Close' } </button> + <AddPerson + addPerson={ addPerson } + /> </div> ); }