skip to Main Content

App.js

import { useState } from 'react';
import ContactList from './ContactList.js';
import EditContact from './EditContact.js';

export default function App() {
    const [
        contacts,
        setContacts
    ] = useState(initialContacts);
    const [
        selectedId,
        setSelectedId
    ] = useState(0);
    const selectedContact = contacts.find(c =>
        c.id === selectedId
    );

    function handleSave(updatedData) {
        const nextContacts = contacts.map(c => {
            if (c.id === updatedData.id) {
                return updatedData;
            } else {
                return c;
            }
        });
        setContacts(nextContacts);
    }
    function handleReset(){
        setContacts(() => initialContacts)
    }

    return (
        <div>
            <ContactList
                contacts={contacts}
                selectedId={selectedId}
                onSelect={id => setSelectedId(id)}
            />
            <hr />
            <EditContact
                key={selectedId}
                initialData={selectedContact}
                onSave={handleSave}
                onReset={ handleReset}
            />
        </div>
    )
}

const initialContacts = [
    { id: 0, name: 'Taylor', email: '[email protected]' },
    { id: 1, name: 'Alice', email: '[email protected]' },
    { id: 2, name: 'Bob', email: '[email protected]' }
];

EditContact.js

import {useState} from 'react';

export default function EditContact({initialData, onSave, onReset}) {
    const [name, setName] = useState(initialData.name);
    const [email, setEmail] = useState(initialData.email);
    return (
        <section>
            <label>
                Name:{' '}
                <input
                    type="text"
                    value={name}
                    onChange={e => setName(e.target.value)}
                />
            </label>
            <label>
                Email:{' '}
                <input
                    type="email"
                    value={email}
                    onChange={e => setEmail(e.target.value)}
                />
            </label>
            <button onClick={() => {
                const updatedData = {
                    id: initialData.id,
                    name: name,
                    email: email
                };
                onSave(updatedData);
            }}>
                Save
            </button>
            <button onClick={() => {
                onReset()
            }}>
                Reset
            </button>
        </section>
    );
}

ContactList.js

export default function ContactList({
  contacts,
  selectedId,
  onSelect
}) {
  return (
    <section>
      <ul>
        {contacts.map(contact =>
          <li key={contact.id}>
            <button onClick={() => {
              onSelect(contact.id);
            }}>
              {contact.id === selectedId ?
                <b>{contact.name}</b> :
                contact.name
              }
            </button>
          </li>
        )}
      </ul>
    </section>
  );
}

This is an editable contact list. You can edit the selected contact’s details and then either press “Save” to update it, or “Reset” to undo your changes.
when I change any contact and then save that, it’s ok, but my problem is when I tap on reset bottom, only the contact list changes but the form fields do not, why?

2

Answers


  1. Chosen as BEST ANSWER

    if we don't want to use useEffect then:

    EditContent.js

    import {useState, useEffect} from 'react';
    
    export default function EditContact({initialData, onSave, onReset}) {
        const [name, setName] = useState(initialData.name);
        const [email, setEmail] = useState(initialData.email);
        const [prevData, setPrevData] = useState(initialData);
    
        if (initialData !== prevData) {
            setPrevData(initialData);
            setName(initialData.name);
            setEmail(initialData.email);
    
        }
        
        // useEffect(() => {
        //     if (initialData) {
        //         setName(initialData.name);
        //         setEmail(initialData.email);
        //     }
        // }, [initialData])
    
        return (
            <section>
                <label>
                    Name:{' '}
                    <input
                        type="text"
                        value={name}
                        onChange={e => setName(e.target.value)}
                    />
                </label>
                <label>
                    Email:{' '}
                    <input
                        type="email"
                        value={email}
                        onChange={e => setEmail(e.target.value)}
                    />
                </label>
                <button onClick={() => {
                    const updatedData = {
                        id: initialData.id,
                        name: name,
                        email: email
                    };
                    onSave(updatedData);
                }}>
                    Save
                </button>
                <button onClick={() => {
    
                    onReset()
                    setName(initialData.name);
                    setEmail(initialData.email);
                    
                }}>
                    Reset
                </button>
            </section>
        );
    }
    

  2. It is because your component EditContact uses its own states and there is nothing that looks if something change to change thoses states.

    You can add a useEffect:

    useEffect(() => {
      if (initialData) {
        setName(initialData.name);
        setEmail(initialData.email);
      }
    }, [initialData])
    

    But then you need also to tell your state of contacts that it is another list so in your reset do this:

    function handleReset(){
      setContacts([...initialContacts])
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search