मैं रिएक्ट हुक और टाइपस्क्रिप्ट का उपयोग करके Redux की मूल बातें सीखने के लिए एक टू-डू/नोट्स ऐप बना रहा हूं।

एक नोट एक आईडी और एक मान से बना होता है। उपयोगकर्ता किसी नोट को जोड़, हटा या संपादित कर सकता है।

जोड़ें/हटाएं यांत्रिकी ठीक काम करते हैं। लेकिन संपादन मेरे लिए मुश्किल है, क्योंकि मैं सवाल कर रहा हूं कि इसे कैसे कार्यान्वित किया जाना चाहिए।

मुझे लगता है कि मेरे रेड्यूसर का कोड ठीक है। समस्या मेरे घटक (Note.tsx) और उसके मूल एक (App.tsx) के बीच है।

जब मैं मान लॉग कर रहा हूं, तो मैं देख सकता हूं कि नोट का नया अद्यतन/संपादित मूल्य रेड्यूसर को नहीं भेजा गया है। परिणामस्वरूप, मेरे नोट को नए मान के साथ संपादित नहीं किया गया है।

मैंने रेडक्स स्टोर को "क्लोनिंग" करने और यहां अपने बदलाव करने की कोशिश की है, लेकिन यह मेरे लिए थकाऊ और अप्राकृतिक लगता है। क्या मुझे सिर्फ अपने Note.tsx घटक से संपादन विधि को कॉल करना चाहिए?

क्या ऐसा करने का कोई साफ/पारंपरिक तरीका है?

यहाँ मेरा कोड है:

ऐप.tsx

function App() {
  const notes = useSelector<NotesStates, NotesStates['notes']>(((state) => state.notes));

  const dispatch = useDispatch();

  const onAddNote = (note: string) => {
    dispatch(addNote(note));
  };

  const onDeleteNote = (note: NoteType) => {
    dispatch(deleteNote(note));
  };

  const onEditNote = (note: NoteType) => {
    dispatch(updateNote(note));
  };

  return (
    <div className="home">
      <NewNoteInput addNote={onAddNote} />
      <hr />
      <ul className="notes">
        {notes.map((note) => (
          <Note
            updateNote={() => onEditNote(note)}
            deleteNote={() => onDeleteNote(note)}
            note={note}
          />
        ))}
      </ul>
    </div>
  );
}

Note.tsx

interface NoteProps {
    deleteNote(): void
    updateNote(noteValue: string | number): void
    note: NoteType
}

const Note: React.FC<NoteProps> = ({ deleteNote, updateNote, note: { id, value } }) => {
  const [isEditing, setIsEditing] = useState(false);
  const [newNoteValue, setNewNoteValue] = useState(value);

  const onDeleteNote = () => {
    deleteNote();
  };

  const onUpdateNote = () => {
    updateNote(newNoteValue);
    setIsEditing(false);
  };

  const handleOnDoubleClick = () => {
    setIsEditing(true);
  };

  const renderBody = () => {
    if (!isEditing) {
      return (
        <>
          {!value && <span className="empty-text">Note is empty</span>}
          <span>{value}</span>
        </>
      );
    }
    return (
      <input
        value={newNoteValue}
        onChange={(e) => setNewNoteValue(e.target.value)}
        onBlur={onUpdateNote}
      />
    );
  };

  return (
    <li className="note" key={id}>
      <span className="note__title">
        Note n°
        {id}
      </span>

      <div className="note__body" onDoubleClick={handleOnDoubleClick}>
        {renderBody()}
      </div>
      <button type="button" onClick={onDeleteNote}>Delete</button>
    </li>
  );
};

export default Note;

और नोट्सReducer.tsx

export interface NotesStates {
    notes: Note[]
}

export interface Note {
    id: number
    value: string
}

const initialState = {
  notes: [],
};

let noteID = 0;

export const notesReducer = (state: NotesStates = initialState, action: NoteAction): NotesStates => {
  switch (action.type) {
    case 'ADD_NOTE': {
      noteID += 1;
      return {
        ...state,
        notes: [...state.notes, {
          id: noteID,
          value: action.payload,
        }],
      };
    }
    case 'UPDATE_NOTE': {
      return {
        ...state,
        notes: state.notes.map((note) => {
          if (note.id === action.payload.id) {
            return {
              ...note,
              value: action.payload.value,
            };
          }
          return note;
        }),
      };
    }
    case 'DELETE_NOTE': {
      return {
        ...state,
        notes: [...state.notes
          .filter((note) => note.id !== action.payload.id)],
      };
    }
    default:
      return state;
  }
};
1
RebootGG 9 अक्टूबर 2020, 16:08

1 उत्तर

सबसे बढ़िया उत्तर

टिप्पणियों में @secan के लिए धन्यवाद, मैंने यह काम किया, साथ ही कुछ बदलाव भी किए।

App.tsx में:

      <Note
        updateNote={onEditNote}
        deleteNote={() => onDeleteNote(note)}
        note={note}
      />

Note.tsx में:

interface NoteProps {
    deleteNote(): void
    updateNote(newNote: NoteType): void // updated the signature
    note: NoteType
}

// Now passing entire object instead of just the value
    const onUpdateNote = (newNote: NoteType) => {
        updateNote(newNote);
        setIsEditing(false);
      };

const renderBody = () => {
    if (!isEditing) {
      return (
        <>
          {!value && <span className="empty-text">Note is empty</span>}
          <span>{value}</span>
        </>
      );
    }
    return (
      <input
        value={newNoteValue}
        onChange={(e) => setNewNoteValue(e.target.value)}
        // modifying current note with updated value
        onBlur={() => onUpdateNote({ id, value: newNoteValue })}
      />
    );
  };
1
RebootGG 9 अक्टूबर 2020, 17:14