So my problem is that i update my state but when i try to use it to approuve my payment the OrderUrl is empty i undestard that setState is asynchrone but how can i avoid this case and update my state immediately.
i have this problem like in two or three page in my website, and i already did some searches some dudes say that i can use useEeffect to update my state by i can’t use it in my case.
JavaScript
x
88
88
1
import React, {useRef, useState, useEffect, useContext} from "react";
2
3
const paimentValidation = () => {
4
5
**// ***************This is my state ConfirmUrl******************* **
6
7
const [orderUrl, setorderUrl] = useState("");
8
const [confirmUrl, setconfirmUrl] = useState("");
9
10
function getOrder() {
11
console.log("order url", orderUrl);
12
var ddata = {arrival: arrival, departure: departure, propertyId: id, hosting_capacity: nbrVoyager};
13
console.log('ddata', ddata);
14
return fetch(orderUrl, {
15
method: "POST",
16
body: JSON.stringify(ddata),
17
headers: {
18
'content-type': 'application/json',
19
20
'Accept': 'application/json',
21
'Authorization': localStorage.getItem('access_token') ? localStorage.getItem('access_token') : ''
22
}
23
24
25
}).then(function (res) {
26
return res.json();
27
}).then(function (data) {
28
localStorage.setItem('data', data);
29
console.log("LOG CONFIRM URL", data.confirmUrl);
30
31
** ******************** // HERE I UPDATE MY STATE************************ **
32
setconfirmUrl(data.confirmUrl);
33
console.log("confirm url", confirmUrl);
34
return data.orderID;
35
})
36
37
}
38
39
function approuve () {
40
** **************AND HERE MY STATE confirmUrl is empty so i get an error with paypal paiment********************** **
41
42
**console.log('CONFIRM URL', confirmUrl);**
43
useEffect(() => alert(confirmUrl), [confirmUrl]);
44
return fetch(confirmUrl, {
45
headers: {
46
'content-type': 'application/json',
47
'Accept': 'application/json',
48
'Authorization': localStorage.getItem('access_token') ? localStorage.getItem('access_token') : ''
49
}
50
}).then(function (res) {
51
return res.json();
52
}).then(function (data) {
53
router.push("paymentsuccess");
54
})
55
}
56
57
return (
58
<LoadingOverlay
59
active={orderUrl == ""}
60
spinner
61
text='Loading ...'
62
>
63
64
<h2 className={styles.titles}>Payer avec</h2>
65
{orderUrl != "" ? (
66
<PayPalScriptProvider options={{
67
"client-id": "AYz2CwrBi8Tu5wdVqsd9IIs3ZdfN0C7cIkA0gczx_AquHaVQQIQJT2M4Neghd04Kje2At62p2ked1-Bu",
68
currency: "EUR",
69
commit: true
70
}}>
71
<PayPalButtons
72
createOrder={getOrder}
73
onApprove={approuve}
74
/>
75
</PayPalScriptProvider>) : (<br/>)}
76
77
78
</div>
79
</div>
80
81
</div>
82
83
</LoadingOverlay>
84
);
85
};
86
87
export default paimentValidation;
88
Advertisement
Answer
You can use your onApprove
handler in the PayPalButtons
component to set some state and then call your approuve
function from inside a useEffect hook that depends on it:
JavaScript
1
22
22
1
const paimentValidation = () => {
2
const [orderUrl, setorderUrl] = useState("");
3
const [confirmUrl, setconfirmUrl] = useState("");
4
const [approved, setApproved] = useState(false);
5
6
useEffect(() => {
7
if(confirmURL && approved) {
8
// we have the confirmation url and approval from the paypal buttons
9
approuve();
10
}
11
}, [approved, confirmUrl]); // runs whenever the approved OR confirmUrl state changes
12
13
14
15
<PayPalButtons
16
createOrder={getOrder}
17
onApprove={() => setApproved(true)} // the button now just sets the state flag, which will trigger the useEffect on the next render
18
/>
19
20
21
};
22