Zen Eddin Allaham نشر 4 أغسطس أرسل تقرير نشر 4 أغسطس لقد انشأت تطبيق ملاحظات الخاص بمسار react في دورة جافا سكريبت لكن استخدمت تايب سكريبت هل كود نظيف او يمكن تحسينه import { useEffect, useState } from "react"; import Note from "./Components/Note"; import Alert from "./Components/Alert"; function App() { interface Notes{ id: number | null; title: string; content: string; } const [notes , setNotes] = useState<Notes[]>(() => { const saveNotes = localStorage.getItem('notes'); return saveNotes ? JSON.parse(saveNotes) : []; }); const [selectedNote , setSelectedNote] = useState<number| null>(null); const [title , setTitle] = useState<string>(''); const [content , setContent] = useState<string >('') const [creating , setCreating] = useState<boolean>(false); const [editing , setEditing] = useState<boolean>(false); const [validationError , setValidationError] = useState<string[]>([]); useEffect(() => { localStorage.setItem('notes' , JSON.stringify(notes)) },[notes]) useEffect(() => { if(validationError.length !==0){ setTimeout(() => { setValidationError([]) },3000) } },[validationError]) const validate = () => { const validationError: string[] = [] let passed = true; if(!title){ validationError.push('الرجاء ادخال عنوان الملاحظة') passed = false } if(!content){ validationError.push('الرجاءادخال محتوى الملاحظة') passed = false } setValidationError(validationError) return passed } const titleChange = (event: React.ChangeEvent<HTMLInputElement>) => { setTitle(event.target.value); } const contentChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => { setContent(event.target.value); } const addToNoteHandler = () => { setCreating(true) setEditing(false); setTitle('') setContent('') } const saveToNoteHandler = () => { if((!validate())) return const note = { id: Date.now(), title: title, content: content } const saveNotes = [...notes , note] setNotes(saveNotes) setSelectedNote(note.id) setCreating(false) setTitle('') setContent('') } const selectNoteHandler = (noteId:number) => { setSelectedNote(noteId) setEditing(false) setCreating(false) } const editNoteHandler = () => { const note = notes.find(note => note.id === selectedNote); setEditing(true) setTitle(note?.title || '') setContent(note?.content || '') } const updateNoteHandler = () => { if((!validate())) return const updateNotes = [...notes]; const noteIndex = updateNotes.findIndex(note => note.id === selectedNote); updateNotes[noteIndex] = { id: selectedNote, title: title, content: content } setNotes(updateNotes); setEditing(false); setTitle('') setContent('') } const deleteNoteHandler = () => { const deleteNotes = [...notes]; const noteIndex = deleteNotes.findIndex(note => note.id === selectedNote); deleteNotes.splice(noteIndex,1) setNotes(deleteNotes) setSelectedNote(null) } const deleteAll = () => { if( window.confirm('هل انت متأكد بحذف جميع الملاحظات')) setNotes([]) setSelectedNote(null) } const getAddNote = () => { return ( <div> <h2>إضافة ملاحظة جديدة</h2> <div> <input type="text" name="title" className="form-input mb-30" placeholder="العنوان" value={title} onChange={titleChange} /> <textarea rows={10} name="content" className="form-input" placeholder="النص" value={content} onChange={contentChange} /> <a href="#" className="button green" onClick={saveToNoteHandler}> حفظ </a> </div> </div> ); }; const getPreview = () => { if(notes.length === 0){ return <h2 className="center">لا يوجد ملاحظة</h2> } else if(!selectedNote){ return <h2 className="center">الرجاء اختيار ملاحظة</h2> } const noteShow = notes.find(note => { return note.id === selectedNote }); let noteDisplay = ( <div> <h2>{noteShow?.title}</h2> <p>{noteShow?.content}</p> </div> ) if(editing){ noteDisplay = ( <div> <h2>تعديل ملاحظة</h2> <div> <input type="text" name="title" className="form-input mb-30" placeholder="العنوان" value={title} onChange={titleChange} /> <textarea rows={10} name="content" className="form-input" placeholder="النص" value={content} onChange={contentChange} /> <a href="#" className="button green" onClick={updateNoteHandler}> تعديل </a> </div> </div> ) } return ( <div> {!editing && <div className="note-operations"> <a href="#" onClick={editNoteHandler}><i className="fa fa-pencil-alt" /> </a> <a href="#" onClick={deleteNoteHandler}><i className="fa fa-trash" /></a> <a href="#" onClick={deleteAll}><i className="fa-solid fa-ban"></i></a> </div> } {noteDisplay} </div> ); }; return ( <div className="App"> <div className="notes-section"> <ul className="notes-list"> {notes.map(note => <Note key={note.id} title={note.title} noteClicked={() => selectNoteHandler(note.id || 0)} active={note.id === selectedNote}/>)} </ul> <button className="add-btn" onClick={addToNoteHandler}>+</button> </div> <div className="preview-section">{creating ? getAddNote() : getPreview()}</div> {validationError.length !==0 && <Alert validationMassge={validationError}/>} </div> ); } export default App; 1 اقتباس
0 Mustafa Suleiman نشر 4 أغسطس أرسل تقرير نشر 4 أغسطس أحسنت في ذلك، فيما يخص TypeScript، فالأفضل تعريف الـ Interfaces في ملف منفصل وليكن types.ts أو interfaces.ts في حال إذا ستُستخدم في أكثر من مكان، أو على الأقل خارج الدالة المكونة. أيضاً، النوع id: number | null غير ضروري بما أنك تستخدم Date.now()، فالملاحظة ستحصل دائمًا على id عند إنشائها، وتستطيع تبسيطه إلى id: number. الحالة الوحيدة التي تكون فيها القيمة null هي للمتغير selectedNote، وهو ما قمت به بشكل صحيح useState<number| null>(null)، لكن id داخل كائن الملاحظة نفسه لن يكون null أبدًا. وبالنسبة لتحديد أنواع الدوال، فمعظم الدوال سواء addToNoteHandler و updateNoteHandler لا تحتوي على أنواع محددة للـ parameters الخاصة بها أو القيمة العائدة منها ، وTypeScript تستنتجها بناءًا على الكود الخاص بالدالة، لكن تحديدها صراحةً يجعل الكود أوضح. وللعلم بإمكانك إنشاء Hook مخصص وقابل لإعادة الاستخدام لإدارة أي حالة في localStorage كالتالي: import { useState, useEffect } from 'react'; function useLocalStorage<T>(key: string, initialValue: T): [T, (value: T) => void] { const [storedValue, setStoredValue] = useState<T>(() => { try { const item = window.localStorage.getItem(key); return item ? JSON.parse(item) : initialValue; } catch (error) { console.error(error); return initialValue; } }); const setValue = (value: T) => { try { const valueToStore = value instanceof Function ? value(storedValue) : value; setStoredValue(valueToStore); window.localStorage.setItem(key, JSON.stringify(valueToStore)); } catch (error) { console.error(error); } }; return [storedValue, setValue]; } export default useLocalStorage; واستخدامه في App.tsx كالتالي: import useLocalStorage from './hooks/useLocalStorage'; const [notes, setNotes] = useLocalStorage<Note[]>('notes', []); اقتباس
السؤال
Zen Eddin Allaham
لقد انشأت تطبيق ملاحظات الخاص بمسار react في دورة جافا سكريبت لكن استخدمت تايب سكريبت هل كود نظيف او يمكن تحسينه
1 جواب على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.