From 59a86d5e10129016e9922fbe3fb9b51fe2a7471e Mon Sep 17 00:00:00 2001 From: Jean-Christophe <jean-christophe.routier@univ-lille.fr> Date: Mon, 29 Jan 2024 09:05:48 +0100 Subject: [PATCH] =?UTF-8?q?composants=20non=20control=C3=A9s=20et=20useRef?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- readme.md | 3 +- src/assets/style/addPerson.css | 9 +++ src/components/addPerson.component.jsx | 42 +++++++++++++ src/components/app.component.jsx | 63 ++++++++++--------- .../personListingController.component.jsx | 5 +- .../personListingControls.component.jsx | 6 +- 6 files changed, 97 insertions(+), 31 deletions(-) create mode 100644 src/assets/style/addPerson.css create mode 100644 src/components/addPerson.component.jsx diff --git a/readme.md b/readme.md index 4307ee8..7818c52 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 0000000..99f8954 --- /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 0000000..b7eac3a --- /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 79920e6..ebf79f2 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 c477855..ef0c744 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 f233637..6157941 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> ); } -- GitLab