Reputation: 33
I am trying to implement Facebook login to my React app.
const [formData, setFormData] = useState({
name: "",
surname: "",
email: "",
password: "",
});
Facebook login here
<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"
/>
The data is coming to:
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 }); */
};
I can't set formData.x. response.first_name or others are working with console.log, but when I try to set the state, it turns nothing.
eg, console.log(formData.name) returns nothing.
Upvotes: 0
Views: 1014
Reputation:
use usestate to set state and useeffect hook to console change , your state doesnt change because its an asynchronous task , in hooks there no callback function in setting state like class , so use 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]);
Upvotes: 1
Reputation: 187252
setFormData({ ...formData, name: response.first_name });
setFormData({ ...formData, surname: response.last_name });
setFormData({ ...formData, email: response.email });
setFormData({ ...formData, password: response.id });
The problem is that formData
does not change until the next render. The value of formData
is the value on the previous render, and it stays that way until the next render. So each of the above lines, sets the old data, plus one changed property. Then the next lines sets the old data with a different changed property, and the property you changed before that is lost.
You just want to call setFormData
once, with all the changes you want. That way you don't need formData
to update at all until after you're done setting everything.
setFormData({
...formData,
name: response.first_name,
surname: response.last_name,
email: response.email,
password: response.id,
});
But looking at your the structure of your state here, you don't need the previous values at all since every key is in the response:
setFormData({
name: response.first_name,
surname: response.last_name,
email: response.email,
password: response.id,
});
Upvotes: 2
Reputation: 1920
useState Hooks are asynchronous, you will not be able to see the data reflected immediately, instead use useEffect to see your result
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]);
Also you could further optimise your code to:
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]);
Upvotes: 0
Reputation: 31693
You should use the previous state or call only one time 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
});
};
Upvotes: 2