Een React-app maken in Visual Studio
In deze zelfstudie maakt u een React-front-end voor een to-do lijstweb-app met behulp van JavaScript en Visual Studio 2022. De code voor deze app is te vinden op ToDoJSWebApp.
Voorwaarden
Zorg ervoor dat u het volgende installeert:
- Visual Studio 2022 of hoger. Ga naar de Visual Studio-downloadpagina om deze gratis te installeren.
- npm (
https://www.npmjs.com/
), dat is opgenomen in Node.js.
De React ToDo List-app maken
Selecteer in Visual Studio File > New > Project om het dialoogvenster Een nieuw project maken te openen, selecteer de React App JavaScript-sjabloon en kies vervolgens Volgende.
Geef het project een naam
TodoWebApp
en selecteer Maken.Hiermee maakt u het JavaScript-project met behulp van het opdrachtregelprogramma vite.
Klik in Solution Explorer met de rechtermuisknop op de map
src
en kies Nieuwe map toevoegen >. en maak een nieuwe map met de naamcomponents
.Het is een algemene conventie om onderdelen in een map met onderdelen te plaatsen, maar dit is niet vereist.
Klik met de rechtermuisknop op de nieuwe map, selecteer Add > React JSX Component File, noem deze
TodoList
en klik op Add.Hiermee maakt u een nieuw JSX-bestand in de map onderdelen.
Open het
TodoList
-onderdeel en vervang de standaardinhoud door het volgende:function TodoList() { return ( <h2>TODO app contents</h2> ); }
In dit onderdeel wordt een koptekst weergegeven die u later gaat vervangen.
Verbind vervolgens dit onderdeel in de app.
App.jsx
is het hoofdonderdeel dat wordt geladen, dat de to-do lijsttoepassing vertegenwoordigt. Dit onderdeel wordt gebruikt in hetmain.jsx
-bestand.Open in Solution Explorer
App.jsx
, verwijder alle importbewerkingen bovenaan en wis de inhoud van de retourinstructie. Het bestand moet er als volgt uitzien.function App() { return ( <> <TodoList /> </> ); } export default App;
Als u het onderdeel TodoList wilt toevoegen, plaatst u de cursor in het fragment en typt u
<TodoL RETURN
. Hiermee worden het onderdeel en de importverklaring toegevoegd.Wis vervolgens de CSS-bestanden.
Open
App.css
en verwijder alle inhoud.Open
Index.css
en verwijder alle inhoud, met uitzondering van de stijlen voor:root
::root { font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; line-height: 1.5; font-weight: 400; color-scheme: light dark; color: rgba(255, 255, 255, 0.87); background-color: #242424; }
De app uitvoeren
Selecteer de knop Foutopsporing starten op de werkbalk of druk op de toetscombinatie F5.
De app wordt geopend in een browservenster.
to-do lijstfuncties toevoegen aan de app
U kunt de app actief laten. Wanneer u wijzigingen aanbrengt, wordt de app automatisch vernieuwd met de nieuwste inhoud met behulp van de ondersteuning voor hot-modulevervanging van Vite. Voor sommige acties, zoals het toevoegen van mappen of het wijzigen van de naam van bestanden, moet u stoppen met foutopsporing en vervolgens de app opnieuw starten, maar in het algemeen kunt u deze op de achtergrond laten draaien terwijl u uw app ontwikkelt. Open het TodoList.jsx
-onderdeel, zodat we het kunnen gaan definiëren.
Open in Solution Explorer
TodoList.jsx
en voeg de gebruikersinterface toe die nodig is om to-do lijstvermeldingen weer te geven en te beheren. Vervang de inhoud door de volgende code:function TodoList() { return ( <div> <h1>TODO</h1> <div> <input type="text" placeholder="Enter a task" required aria-label="Task text" /> <button className="add-button" aria-label="Add task">Add</button> </div> <ol id="todo-list"> <p>existing tasks will be shown here</p> </ol> </div> ); } export default TodoList;
Met de voorgaande code wordt een invoervak toegevoegd voor de nieuwe to-do taak en een knop om de invoer in te dienen. Vervolgens sluit je de knop Toevoegen aan. Gebruik de useState React-hook om twee statusvariabelen toe te voegen, één voor de taak die wordt toegevoegd en een andere om de bestaande taken op te slaan. Voor deze zelfstudie worden de taken opgeslagen in het geheugen en niet in permanente opslag.
Voeg de volgende importinstructie toe aan
TodoList.jsx
omuseState
te importeren.import { useState } from 'react'
Gebruik vervolgens die hook om de statusvariabelen te maken. Voeg de volgende code toe in de functie
TodoList
boven de retourinstructie.const [tasks, setTasks] = useState(["Drink some coffee", "Create a TODO app", "Drink some more coffee"]); const [newTaskText, setNewTaskText] = useState("");
Hiermee worden twee variabelen,
tasks
ennewTaskText
, ingesteld voor de gegevens en twee functies die u kunt aanroepen om deze variabelen,setTasks
ensetNewTasks
bij te werken. Wanneer een waarde voor een statusvariabele wordt gewijzigd, wordt het onderdeel automatisch opnieuw gegenereerd door React.U bent bijna klaar om TodoList.jsx- bij te werken om de to-do items als een lijst weer te geven, maar er is een belangrijk React-concept om eerst te leren.
Wanneer u in React een lijst met items weergeeft, moet u een sleutel toevoegen om elk item in de lijst uniek te identificeren. Deze functie wordt uitgebreid uitgelegd in de React-documenten op Rendering Lists, maar hier leert u de basisbeginselen. U hebt een lijst met to-do items die moeten worden weergegeven en u moet een unieke sleutel voor elk item koppelen. De sleutel voor elk item mag niet worden gewijzigd en daarom kunt u de index van het item in de matrix niet gebruiken als sleutel. U hebt een id nodig die gedurende de levensduur van deze waarden niet verandert. U gebruikt randomUUID() om een unieke id te maken voor elk to-do item.
Maak TodoList.jsx met behulp van een UUID als de sleutel voor elk to-do item. Werk TodoList.jsx- bij met de volgende code.
import React, { useState } from 'react'; const initialTasks = [ { id: self.crypto.randomUUID(), text: 'Drink some coffee' }, { id: self.crypto.randomUUID(), text: 'Create a TODO app' }, { id: self.crypto.randomUUID(), text: 'Drink some more coffee' } ]; function TodoList() { const [tasks, setTasks] = useState(initialTasks); const [newTaskText, setNewTaskText] = useState(""); return ( <article className="todo-list" aria-label="task list manager"> <header> <h1>TODO</h1> <form className="todo-input" aria-controls="todo-list"> <input type="text" placeholder="Enter a task" value={newTaskText} /> <button className="add-button"> Add </button> </form> </header> <ol id="todo-list" aria-live="polite" aria-label="task list"> {tasks.map((task, index) => <li key={task.id}> <span className="text">{task.text}</span> </li> )} </ol> </article> ); } export default TodoList;
Omdat de id-waarden buiten de functie TodoList zijn toegewezen, kunt u ervoor zorgen dat de waarden niet worden gewijzigd als de pagina opnieuw wordt weergegeven. Wanneer u de app in deze toestand probeert, ziet u dat u niet kunt typen in het takenlijst-invoerveld. Dit komt doordat het invoerelement is gebonden aan
newTaskText
, die is geïnitialiseerd naar een lege tekenreeks. Als u wilt dat gebruikers nieuwe taken kunnen toevoegen, moet u deonChange
gebeurtenis op dat besturingselement afhandelen. U moet ook de ondersteuning voor de knop Toevoegen implementeren.Voeg de vereiste functies meteen vóór de retourinstructie toe in de TodoList-functie.
function handleInputChange(event) { setNewTaskText(event.target.value); } function addTask() { if (newTaskText.trim() !== "") { setTasks(t => [...t, { id: self.crypto.randomUUID(), text: newTaskText }]); setNewTaskText(""); } event.preventDefault(); }
In de functie
handleInputChanged
wordt de nieuwe waarde uit het invoerveld doorgegeven viaevent.target.value
en die waarde wordt gebruikt om de waarde voor denewTaskText
variabele bij te werken metsetNewTaskText
. Voeg in de functieaddTask
de nieuwe taak toe aan de lijst met bestaande taken met behulp vansetTasks
en stel de id van het item in als een nieuwe UUID-waarde. Werk het invoerelement bij omonChange={handleInputChange}
op te nemen en werk de knop Toevoegen bij omonClick={addTask}
op te nemen. Met deze code wordt de gebeurtenis aan de functie gekoppeld die deze gebeurtenis verwerkt. Hierna moet u een nieuwe taak aan de takenlijst kunnen toevoegen. Nieuwe taken worden onder aan de lijst toegevoegd. Als u deze app nuttiger wilt maken, moet u ondersteuning toevoegen om taken te verwijderen en een taak omhoog of omlaag te verplaatsen.Voeg de functies toe ter ondersteuning van verwijderen, omhoog en omlaag gaan en werk vervolgens de markeringen bij om een knop weer te geven voor elke actie. Voeg de volgende code toe in de functie TodoList boven de retourinstructie.
function deleteTask(id) { const updatedTasks = tasks.filter(task => task.id != id); setTasks(updatedTasks); } function moveTaskUp(index) { if (index > 0) { const updatedTasks = [...tasks]; [updatedTasks[index], updatedTasks[index - 1]] = [updatedTasks[index - 1], updatedTasks[index]]; setTasks(updatedTasks); } } function moveTaskDown(index) { if (index < tasks.length) { const updatedTasks = [...tasks]; [updatedTasks[index], updatedTasks[index + 1]] = [updatedTasks[index + 1], updatedTasks[index]]; setTasks(updatedTasks); } }
De verwijderfunctie neemt de taak-id in en verwijdert deze uit de lijst en gebruikt de matrixfilter() methode om een nieuwe matrix te maken die het geselecteerde item uitsluit en roept vervolgens
setTasks()
aan. De andere twee functies nemen de index van het item in omdat dit werk specifiek is voor de volgorde van items. ZowelmoveTaskUp()
alsmoveTaskDown()
gebruiken array-destructureringstoewijzing om de geselecteerde taak om te wisselen met zijn buur.Werk vervolgens de weergave bij om deze drie knoppen op te nemen. Werk de retourinstructie bij zodat deze het volgende bevat.
return ( <article className="todo-list" aria-label="task list manager"> <header> <h1>TODO</h1> <form className="todo-input" onSubmit={addTask} aria-controls="todo-list"> <input type="text" required autoFocus placeholder="Enter a task" value={newTaskText} aria-label="Task text" onChange={handleInputChange} /> <button className="add-button" aria-label="Add task"> Add </button> </form> </header> <ol id="todo-list" aria-live="polite"> {tasks.map((task, index) => <li key={task.id}> <span className="text">{task.text}</span> <button className="delete-button" onClick={() => deleteTask(task.id)}> 🗑️ </button> <button className="up-button" onClick={() => moveTaskUp(index)}> ⇧ </button> <button className="down-button" onClick={() => moveTaskDown(index)}> ⇩ </button> </li> )} </ol> </article> );
U hebt de knoppen toegevoegd die nodig zijn om de taken uit te voeren die we eerder hebben besproken. U gebruikt Unicode-tekens als pictogrammen op de knoppen. In de markeringen zijn er enkele kenmerken toegevoegd ter ondersteuning van het later toevoegen van css. Mogelijk ziet u ook het gebruik van aria-kenmerken om de toegankelijkheid te verbeteren. Dit is optioneel, maar ten zeerste aanbevolen. Als u de app uitvoert, moet deze eruitzien als in de volgende afbeelding.
U moet nu het volgende kunnen uitvoeren in de todo-web-app.
- Taak toevoegen
- Taak verwijderen
- Taak omhoog verplaatsen
- Taak omlaag verplaatsen
Deze functies werken, maar u kunt herstructureren om een herbruikbaar onderdeel te maken om de to-do items weer te geven. De markering voor het to-do-item gaat naar een nieuw onderdeel, TodoItem. Omdat het beheer van de lijst in het onderdeel Todo blijft, kunt u callbacks doorgeven aan de knoppen Verwijderen en Verplaatsen.
Om te beginnen klikt u met de rechtermuisknop op de map components in Solution Explorer en selecteert u Add > New Item.
Selecteer in het dialoogvenster dat wordt geopend het React JSX Component File, geef het de naam TodoItem en selecteer Toevoegen.
Voeg de volgende code toe aan de TodoItem.
In deze code geeft u de taak en callbacks door als eigenschappen aan dit nieuwe onderdeel.
import PropTypes from 'prop-types'; function TodoItem({ task, deleteTaskCallback, moveTaskUpCallback, moveTaskDownCallback }) { return ( <li aria-label="task" > <span className="text">{task}</span> <button type="button" aria-label="Delete task" className="delete-button" onClick={() => deleteTaskCallback()}> 🗑️ </button> <button type="button" aria-label="Move task up" className="up-button" onClick={() => moveTaskUpCallback()}> ⇧ </button> <button type="button" aria-label="Move task down" className="down-button" onClick={() => moveTaskDownCallback()}> ⇩ </button> </li> ); } TodoItem.propTypes = { task: PropTypes.string.isRequired, deleteTaskCallback: PropTypes.func.isRequired, moveTaskUpCallback: PropTypes.func.isRequired, moveTaskDownCallback: PropTypes.func.isRequired, }; export default TodoItem;
De voorgaande code bevat de markeringen van het onderdeel Todo en aan het einde van de code declareert u de
PropTypes
. Props worden gebruikt om gegevens van een oudercomponent door te geven aan kindcomponenten. Zie Props doorgeven aan een onderdeel – Reactvoor meer informatie over props. Omdat de verwijder- en verplaatsingsfuncties worden doorgegeven als callbacks, moet deonClick
handler worden bijgewerkt om deze callbacks aan te roepen.Voeg de vereiste code toe. De volledige code voor TodoList die gebruikmaakt van het onderdeel TodoItem wordt hier weergegeven.
import React, { useState } from 'react' import TodoItem from './TodoItem' const initialTasks = [ { id: self.crypto.randomUUID(), text: 'Drink some coffee' }, { id: self.crypto.randomUUID(), text: 'Create a TODO app' }, { id: self.crypto.randomUUID(), text: 'Drink some more coffee' } ]; function TodoList() { const [tasks, setTasks] = useState(initialTasks); const [newTaskText, setNewTaskText] = useState(""); function handleInputChange(event) { setNewTaskText(event.target.value); } function addTask() { if (newTaskText.trim() !== "") { setTasks(t => [...t, { id: self.crypto.randomUUID(), text: newTaskText }]); setNewTaskText(""); } event.preventDefault(); } function deleteTask(id) { const updatedTasks = tasks.filter(task => task.id !== id); setTasks(updatedTasks); } function moveTaskUp(index) { if (index > 0) { const updatedTasks = [...tasks]; [updatedTasks[index], updatedTasks[index - 1]] = [updatedTasks[index - 1], updatedTasks[index]]; setTasks(updatedTasks); } } function moveTaskDown(index) { if (index < tasks.length) { const updatedTasks = [...tasks]; [updatedTasks[index], updatedTasks[index + 1]] = [updatedTasks[index + 1], updatedTasks[index]]; setTasks(updatedTasks); } } return ( <article className="todo-list" aria-label="task list manager"> <header> <h1>TODO</h1> <form onSubmit={addTask} aria-controls="todo-list"> <input type="text" required placeholder="Enter a task" value={newTaskText} aria-label="Task text" onChange={handleInputChange} /> <button className="add-button" aria-label="Add task"> Add </button> </form> </header> <ol id="todo-list" aria-live="polite"> {tasks.map((task, index) => <TodoItem key={task.id} task={task.text} deleteTaskCallback={() => deleteTask(task.id)} moveTaskUpCallback={() => moveTaskUp(index)} moveTaskDownCallback={() => moveTaskDown(index)} /> )} </ol> </article> ); } export default TodoList;
Nu wordt het onderdeel TodoItem gebruikt om elk to-do item weer te geven. U ziet dat de sleutel is ingesteld op
task.id
, die de UUID-waarde voor die taak bevat. Wanneer u de app uitvoert, ziet u geen wijzigingen in het uiterlijk of gedrag van de app omdat u deze hebt geherstructureerd om TodoItem te gebruiken.Nu alle basisfuncties worden ondersteund, is het tijd om wat stijl toe te voegen om het er mooi uit te laten zien. Begin met het toevoegen van een koppeling in Index.html voor een lettertypefamilie, Inter, die u voor deze app gaat gebruiken. In Index.htmlzijn er enkele andere items die moeten worden opgeschoond. De titel moet worden bijgewerkt en u wilt het vite.svg-bestand vervangen dat momenteel als pictogram wordt gebruikt.
Werk Index.html bij met de volgende inhoud.
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/checkmark-square.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>TODO app</title> <link href='https://fonts.googleapis.com/css?family=Inter' rel='stylesheet'> <script type="module" defer src="/src/main.jsx"></script> </head> <body> </body> </html>
Bewerk bestand main.jsx om
root
te vervangen doormain
bij het aanroepen vancreateRoot
.De volledige code voor main.jsx- wordt hier weergegeven.
import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import App from './App.jsx' import './index.css' createRoot(document.querySelector('main')).render( <StrictMode> <App /> </StrictMode>, )
Naast deze wijzigingen is het bestand checkmark-square.svg toegevoegd aan de openbare map. Dit is een SVG van het FluentUI-icoon "vierkante-vinkje" dat u direct kunt downloaden. (Er is een pakket dat u kunt gebruiken voor een meer geïntegreerde ervaring, maar dat valt buiten het bereik van dit artikel.)
Werk vervolgens de stijlen van het onderdeel TodoList bij.
Voeg in de map onderdelen een nieuw CSS-bestand toe met de naam TodoList.css. U kunt met de rechtermuisknop op het project klikken en Toevoegen > nieuw item selecteren en vervolgens opmaakmodelselecteren. Geef het bestand de naam TodoList.css.
Voeg de volgende code toe aan TodoList.css.
.todo-list { background-color: #1e1e1e; padding: 1.25rem; border-radius: 0.5rem; box-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.3); width: 100%; max-width: 25rem; } .todo-list h1 { text-align: center; color: #e0e0e0; } .todo-input { display: flex; justify-content: space-between; margin-bottom: 1.25rem; } .todo-input input { flex: 1; padding: 0.625rem; border: 0.0625rem solid #333; border-radius: 0.25rem; margin-right: 0.625rem; background-color: #2c2c2c; color: #e0e0e0; } .todo-input .add-button { padding: 0.625rem 1.25rem; background-color: #007bff; color: #fff; border: none; border-radius: 0.25rem; cursor: pointer; } .todo-input .add-button:hover { background-color: #0056b3; } .todo-list ol { list-style-type: none; padding: 0; } .todo-list li { display: flex; justify-content: space-between; align-items: center; padding: 0.625rem; border-bottom: 0.0625rem solid #333; } .todo-list li:last-child { border-bottom: none; } .todo-list .text { flex: 1; } .todo-list li button { background: none; border: none; cursor: pointer; font-size: 1rem; margin-left: 0.625rem; color: #e0e0e0; } .todo-list li button:hover { color: #007bff; } .todo-list li button.delete-button { color: #ff4d4d; } .todo-list li button.up-button, .todo-list li button.down-button { color: #4caf50; }
Bewerk vervolgens TodoList.jsx- om de volgende import toe te voegen boven aan het bestand.
import './TodoList.css';
Vernieuw de browser nadat u de wijzigingen hebt opgeslagen. Dit moet de stijl van de app verbeteren. De app moet er als volgt uitzien.
U hebt nu een werkende to-do lijst-app gemaakt waarin de to-do items in het geheugen worden opgeslagen. Vanaf dit punt kunt u de app bijwerken om de to-do items op te slaan in localStorage/IndexedDb-, of dit integreren met een database aan de serverzijde of een andere back-end, voor meer permanente opslag.
Samenvatting
In deze zelfstudie hebt u een nieuwe React-app gemaakt met Visual Studio. De app bestaat uit een to-do lijst, waaronder ondersteuning voor het toevoegen van taken, het verwijderen van taken en het opnieuw ordenen ervan. U hebt twee nieuwe React-onderdelen gemaakt en deze in deze zelfstudie gebruikt.
Hulpmiddelen
- Code voor dit voorbeeld op ToDoJSWebApp
- Visual Studio JavaScript- en TypeScript-projecten