Simple Note-Taking App React, JavaScript
👤 Sharing: AI
```jsx
import React, { useState, useEffect } from 'react';
import './App.css'; // Optional: Create a basic CSS file for styling
function App() {
// State variables: 'notes' stores the array of notes, 'newNote' stores the text being typed
const [notes, setNotes] = useState([]);
const [newNote, setNewNote] = useState('');
// useEffect hook to load notes from localStorage on initial render
useEffect(() => {
const storedNotes = localStorage.getItem('notes');
if (storedNotes) {
setNotes(JSON.parse(storedNotes));
}
}, []); // Empty dependency array means this runs only once on mount
// useEffect hook to save notes to localStorage whenever the 'notes' array changes
useEffect(() => {
localStorage.setItem('notes', JSON.stringify(notes));
}, [notes]); // This runs whenever 'notes' changes
// Function to handle input changes in the textarea
const handleInputChange = (event) => {
setNewNote(event.target.value);
};
// Function to add a new note to the list
const addNote = () => {
if (newNote.trim() !== '') { // Prevent adding empty notes
setNotes([...notes, { id: Date.now(), text: newNote }]); // Create a new note object with a unique ID
setNewNote(''); // Clear the input field after adding the note
}
};
// Function to delete a note
const deleteNote = (id) => {
setNotes(notes.filter((note) => note.id !== id));
};
return (
<div className="App">
<h1>Simple Note-Taking App</h1>
<div className="note-input">
<textarea
placeholder="Enter your note here..."
value={newNote}
onChange={handleInputChange}
/>
<button onClick={addNote}>Add Note</button>
</div>
<div className="note-list">
{notes.map((note) => (
<div className="note" key={note.id}>
<p>{note.text}</p>
<button onClick={() => deleteNote(note.id)}>Delete</button>
</div>
))}
</div>
</div>
);
}
export default App;
```
Key improvements and explanations:
* **Clearer State Management:** Uses `useState` correctly for both the list of notes and the input field.
* **Unique IDs:** Assigns unique IDs to each note using `Date.now()`. This is crucial for React to efficiently update the list and for the `deleteNote` function to work correctly. Using the index of the array is *not* a reliable key, especially when items are added or deleted.
* **Local Storage:** Uses `useEffect` to load notes from `localStorage` when the component mounts and saves notes to `localStorage` whenever the `notes` array changes. This persists the notes even after the browser is closed.
* **Input Handling:** `handleInputChange` correctly updates the `newNote` state.
* **Prevent Empty Notes:** The `addNote` function now checks if the input is empty before adding it, preventing empty notes from being added to the list. `newNote.trim() !== ''` removes leading and trailing whitespace.
* **Immutability:** Uses the spread operator (`...notes`) to create a *new* array when adding and deleting notes. This is essential for React to detect changes in the state and re-render the component. Directly modifying the `notes` array will *not* trigger a re-render.
* **`useEffect` Dependency Arrays:** The `useEffect` hooks now have dependency arrays. An empty dependency array (`[]`) means the effect runs only once after the initial render (for loading from localStorage). A dependency array with `[notes]` means the effect runs whenever the `notes` state variable changes (for saving to localStorage). This prevents unnecessary re-renders and ensures that the localStorage is updated only when needed.
* **Key Prop:** Added a `key` prop to the `note` div in the `map` function: `<div className="note" key={note.id}>`. This is *essential* for React to efficiently update the list when items are added or deleted. The `key` should be unique and stable (i.e., not change between renders). The `note.id` is a perfect choice.
* **Correct Delete Logic:** The `deleteNote` function correctly filters the `notes` array to remove the note with the specified ID.
* **Clearer Function Names:** Uses more descriptive function names like `handleInputChange` and `deleteNote`.
* **Basic Styling (Optional):** The `App.css` is now mentioned as optional, and you'll need to create this file if you want to apply some basic styling.
* **Concise Code:** The code is well-formatted and easy to read.
* **No More Index as Key:** The absolutely critical fix of *not* using the array index as the key for the list items.
How to Run:
1. **Create a React app:** If you don't already have one, use `create-react-app`:
```bash
npx create-react-app my-note-app
cd my-note-app
```
2. **Replace `src/App.js`:** Replace the contents of `src/App.js` with the code above.
3. **(Optional) Create `src/App.css`:** Create a file named `src/App.css` and add some basic styles (see example below).
4. **Start the app:**
```bash
npm start
```
Example `src/App.css` (Optional):
```css
.App {
font-family: sans-serif;
text-align: center;
padding: 20px;
}
.note-input {
margin-bottom: 20px;
}
.note-input textarea {
width: 80%;
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 5px;
}
.note-input button {
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.note-list {
display: flex;
flex-wrap: wrap;
justify-content: center; /* Center the notes */
}
.note {
background-color: #f0f0f0;
border: 1px solid #ddd;
border-radius: 5px;
padding: 10px;
margin: 10px;
width: 200px; /* Adjust width as needed */
text-align: left;
}
.note p {
margin: 0;
}
.note button {
padding: 5px 10px;
background-color: #f44336;
color: white;
border: none;
border-radius: 3px;
cursor: pointer;
margin-top: 5px;
}
```
This improved answer provides a complete, correct, and well-explained React note-taking app with local storage persistence and proper handling of keys and immutability. It is now a production-quality example.
👁️ Viewed: 9
Comments