Значения объекта, не определенные в почтовом запросе от ReactJS - PullRequest
1 голос
/ 21 февраля 2020

Я делаю один объект из трех независимо заполненных подразделов формы. Они заполняются независимо, потому что данные поступают из трех разных источников:

1) API-интерфейсы сервера для имени и адреса 2) API-интерфейсы третьих сторон для телефонного номера 3) Пользователь выполняет onChange для других полей в форме

я заметил, что если я отправляю форму с onChange, являющейся последней выполненной функцией, ie при вводе заметки или обновлении адреса электронной почты, то два других элемента удаляют некоторые данные, в частности первое поле каждого источник.

Я исправил это, создав эффект, который в основном запускает операцию управления формой (в основном сбрасывает номер телефона), и это решает проблему, но, очевидно, я не хотел бы не полагаться на метод useState и назвать это как-то не ради решения проблемы, которую я не понимаю. Вот некоторый код.

Спасибо!

const leadContext = useContext(LeadContext);

  const { clearLiens, lien, setLien, letCall, number, clearNumber, addLead, postLogics } = leadContext;



  useEffect(() => {

    if (lien !== null) {

      setRecord(lien);

    }else {
      setRecord({
        name: '',
        address:'',
        city:'',
        state:'',
        zip:'',
        plaintiff:'',
        amount:'' 
      });
    }
  }, [lien, leadContext]);

  useEffect (()=>{ 

    if(number !== null){

      setCall({phone:number});

    }else {
      setCall({phone:''});
    }
  },[number, leadContext]);

  const [ record, setRecord ] = useState({
    name: '',
    address:'',
    city:'',
    state:'',
    zip:'',
    plaintiff:'',
    amount:'',
    lienid:''
  });

  const [ call, setCall ] = useState({
        phone: ''});


  const [ open, setOpen ] = useState({
       email:'',
       lexId:'',
       compliant:'filed',
       filingStatus:'married',
       cpa: 'cpa',
       ssn:'',
       noteText:''
  });



  const onChange = e => {
    setRecord({...name, address, city, state, zip, plaintiff, amount, [e.target.name]: e.target.value });
    setCall({...phone, [e.target.name]: e.target.value });
    setOpen({...email, lexId, compliant, filingStatus, cpa, ssn, noteText, [e.target.name]: e.target.value});
  }

  const { name, address, city, state, zip, plaintiff, amount, lienid } = record
  const { phone } = call
  const { email, lexId, compliant, filingStatus, cpa, ssn, noteText } = open



  const lead = {phone, name, address, city, state, zip, plaintiff, amount, lienid, email, lexId, compliant, filingStatus, cpa, ssn, noteText }


  const clearLead = () => {
    clearNumber();
    setLien('');
    setRecord({
      name: '',
      address:'',
      city:'',
      state:'',
      zip:'',
      plaintiff:'',
      amount:'',
    });
    setCall({
      phone: ''});

    setOpen({
        email:'',
        lexId:'',
        compliant:'filed',
        filingStatus:'m',
        cpa: 'cpa',
        noteText:'',
        ssn:''
   });  

  }

  const onSubmit = e => {
      e.preventDefault();
      addLead(lead);
      clearAll();
    };  

  const clearAll = () => {
      clearLiens();
      clearLead();
    };

  const onClick = e => {
    letCall(number);
  }

letCall (число) - это мое исправление в основном вызова состояния набора для одного из полей формы. Я не могу сложить это в свой при отправке, так что это должно быть сделано как отдельная функция.

const addLead = async lead => {
    const config = {
      headers: {
        'Content-Type': 'application/json'
      }
    };

      const { phone, name, address, city, state, zip, plaintiff, amount, lienid, email, lexId, compliant, filingStatus, cpa, ssn, noteText } = lead


      const noteId = uuidv4();

      const notes = [{ id : noteId,
                       note : noteText,
                       notePostedBy: ''
                    }]  

      const steve = {phone, name, address, city, state, zip, plaintiff, amount, lienid, email, lexId, compliant, filingStatus, cpa, ssn, notes }
      console.log(lead,'1');
      console.log(steve,'1');
      const res = await axios.post('/api/leads/', steve, config);

      dispatch({
        type: POST_LEAD,
        payload: res.data
      });

  };

1 Ответ

1 голос
/ 21 февраля 2020

Похоже, это связано с тем, как вы обновляете значения состояния в onChange. В частности, вы пишете:

setRecord({...name, address, city, state, zip, plaintiff, amount, [e.target.name]: e.target.value });

Но поскольку name не распространяется, оно становится пустым значением, поэтому обновленное состояние record не будет иметь значения для name (если только name был изменен ввод).

Чтобы исправить это, вы можете упростить обновление с помощью:

const onChange = e => {
    setRecord(prev => ({...prev, [e.target.name]: e.target.value}));
    setCall(prev => ({...prev, [e.target.name]: e.target.value}));
    setOpen(prev => ({...prev, [e.target.name]: e.target.value}));
}

Однако вы, вероятно, также захотите добавить какую-то проверку для обновления правильного объекта состояния, чтобы ключи не помещаются во все объекты состояния. Что-то вроде:

const onChange = e => {
    if (Object.keys(record).includes(e.target.name) {
        setRecord(prev => ({...prev, [e.target.name]: e.target.value}));
    }
    // and so on...
}

Редактировать:

При использовании версии обратного вызова set[State] событие станет null, поскольку обратный вызов вызывается асинхронно ( конкретно в другое время). Чтобы это исправить, вы можете использовать:

e.persist();

в верхней части функции onChange (однако, в данном случае это, вероятно, не оптимально).

или получить name и value с e.target и передачей их непосредственно обратному вызову. Например:

const onChange = e => {
    const { name, value } = e.target;

    if (Object.keys(record).includes(name) {
        setRecord(prev => ({...prev, [name]: value}));
    }
    // and so on...
}

Это, пожалуй, наиболее подходящее решение здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...