I'm new with Node.js and I'm having some troubles understanding it's logic. I created a page with few SELECT elements. The options for each SELECT are loaded from server with axios. Then user selects options and press Save button to save them by sending to server by axios post request. The code is:
export default function AddVault(props) {
const [inputs, setInputs] = useState({
wallet: "",
blockchain: "",
platform: "",
});
const [blockchains, setBlockchains] = useState([]);
const [platforms, setPlatforms] = useState([]);
// change state when user choose option in SELECT element
function InputChange(evt) {
const value = evt.target.value;
setInputs({
...inputs,
[evt.target.name]: value,
});
}
useEffect(() => {
const getBP = async () => {
const blockchains = await Axios.get(
process.env.REACT_APP_SRV "/api/blockchains"
);
// the options for Blockchain SELECT
setBlockchains(blockchains.data);
setInputs({
...inputs,
blockchain: blockchains.data[0].blockchain,
});
console.log("i1=", inputs);
const platforms = await Axios.get(
process.env.REACT_APP_SRV
"/api/platforms?blockchain="
inputs.blockchain
);
// the options for Platform SELECT
setPlatforms(platforms.data.response);
setInputs({
...inputs,
platform: platforms.data.response[0].title,
});
console.log("i2=", inputs);
};
getBP();
console.log("i3=", inputs);
}, []);
The Axios requests work ok, setBlockchains and setPlatforms are setting the appropriate states, but the problem is all console logs output the initial "inputs" variable, i.e.
i3= {wallet: '', blockchain: '', platform: ''}
i1= {wallet: '', blockchain: '', platform: ''}
i2= {wallet: '', blockchain: '', platform: ''}
And when I'm sending form with axios with default loaded values I have the following "inputs" variable
save: inputs = {wallet: '', blockchain: '', platform: 'Autofarm'}
i.e. the inputs.blockchain is not set. It seems the each setInputs in useEffect is getting inputs variable with default (initial) state.
It seems to me I'm working with local "inputs" state variable inside useEffect function, not with global "inputs" state variable. Is it correct? If yes, then how can I access global state variable inside useEffect? If no, then why inputs.blockchain is not set?
Best regards, Alex.
CodePudding user response:
In your code, you're calling console.log
before the changes have been applied to the state.
To really see the changes made to inputs
, do this:
useEffect(() => {
console.log(inputs);
}, [inputs])
CodePudding user response:
In function get BP() when you call
// the options for Blockchain SELECT
setBlockchains(blockchains.data);
setInputs({
...inputs,
blockchain: blockchains.data[0].blockchain,
});
console.log("i1=", inputs);
you expect the updated value to get logged. But since useState is Async in nature it continues to executes the other instructions while one is in process. Thus your console.log gives initial values. Same goes for
console.log("i2=", inputs);
and
getBP();
console.log("i3=", inputs);
As there is no callback too like class-based setState() functions; in hooks, try using useEffect to track the change in inputs.
useEffect(()=>{
console.log(inputs);
},[inputs])
This might be helpful : https://dev.to/shareef/react-usestate-hook-is-asynchronous-1hia