React State Hook - я не могу установить состояние - PullRequest
0 голосов
/ 07 мая 2020

Я пытаюсь реализовать вход через Facebook в свое приложение React.

const [formData, setFormData] = useState({
    name: "",
    surname: "",
    email: "",
    password: "",
  });

Вход в Facebook здесь

<FacebookLogin
 appId=""
 autoLoad={true}
 fields="first_name,last_name,email,id"
 onClick={(e) => componentClicked(e)}
 callback={(response) => responseFacebook(response)}
 textButton={msg}
 cssClass="btn btn-primary btn-sm"
 icon="fa-facebook"
 />

Данные поступают на:

const responseFacebook = (response) => {
    setFormData({ ...formData, name: response.first_name });
    setFormData({ ...formData, surname: response.last_name });
    setFormData({ ...formData, email: response.email });
    setFormData({ ...formData, password: response.id });
    console.log(formData.name);
    console.log(formData.surname);
    /* register({ name, surname, email, password }); */
  };

Я не могу установить formData.x. response.first_name или другие работают с console.log, но когда я пытаюсь установить состояние, ничего не получается.

например, console.log (formData.name) ничего не возвращает.

Ответы [ 4 ]

2 голосов
/ 07 мая 2020
setFormData({ ...formData, name: response.first_name });
setFormData({ ...formData, surname: response.last_name });
setFormData({ ...formData, email: response.email });
setFormData({ ...formData, password: response.id });

Проблема в том, что formData не меняется до следующего рендера. Значение formData - это значение на предыдущем рендере, и оно остается таким до следующего рендеринга. Таким образом, каждая из вышеперечисленных строк устанавливает старые данные плюс одно измененное свойство. Затем следующие строки устанавливают для старых данных другое измененное свойство, и свойство, которое вы изменили до этого, теряется.

Вы просто хотите вызвать setFormData один раз со всеми необходимыми изменениями. Таким образом, вам не потребуется formData для обновления, пока вы не закончите все настройки.

setFormData({
  ...formData,
  name: response.first_name,
  surname: response.last_name,
  email: response.email,
  password: response.id,
});

Но, глядя на структуру вашего состояния здесь, вы этого не сделаете. вообще нужны предыдущие значения, так как каждый ключ находится в ответе:

setFormData({
  name: response.first_name,
  surname: response.last_name,
  email: response.email,
  password: response.id,
});
2 голосов
/ 07 мая 2020

Вы должны использовать предыдущее состояние или вызывать только один раз setFormData.

// using previous state
// this solves your problem but isn't that good
// because you don't need to call it many times
const responseFacebook = (response) => {
    setFormData(prev => ({ ...prev, name: response.first_name });
    setFormData(prev => ({ ...prev, surname: response.last_name });
    setFormData(prev => ({ ...prev, email: response.email });
    setFormData(prev => ({ ...prev, password: response.id });
};

OR

// calling only once
const responseFacebook = (response) => {
    setFormData({ 
         name: response.first_name,
         surname: response.last_name,
         email: response.email,
         password: response.id 
    });
};
1 голос
/ 07 мая 2020

используйте usestate для установки состояния и useeffect hook для изменения консоли, ваше состояние не меняется, потому что это асинхронная задача, в хуках нет функции обратного вызова в настройке состояния, например class, поэтому используйте useEffect

const responseFacebook = (response) => {
    setFormData({ 
      ...formData, 
      name: response.first_name 
      surname: response.last_name,
      email: response.email,
      password: response.id 
    });
});

useEffect(() => {
   console.log(formData.name);
    console.log(formData.surname);
}, [formData]);
0 голосов
/ 07 мая 2020

хуки useState асинхронны, вы не сможете сразу увидеть отраженные данные, вместо этого используйте useEffect, чтобы увидеть свой результат

const responseFacebook = (response) => {
    setFormData({ ...formData, name: response.first_name });
    setFormData({ ...formData, surname: response.last_name });
    setFormData({ ...formData, email: response.email });
    setFormData({ ...formData, password: response.id });
    console.log(formData.name); // This won't show the results
    console.log(formData.surname); // This won't show the results
    /* register({ name, surname, email, password }); */ // This won't show the results
  };

useEffect(() => {
    // action on update of formData
 console.log(formData);
}, [formData]);

Также вы можете дополнительно оптимизировать свой код, чтобы:

   setFormData({ 
    ...formData,
    name: response.first_name,
    surname: response.last_name,
    email: response.email,
    password: response.id 
   });

useEffect(() => {
    // action on update of formData
 console.log(formData);
}, [formData]);
...