I am trying to create a simple React front-end for a smart contract which is a To-Do List. My problem is with the useEffect
hook. I am trying to do a for loop inside the effect hook, and putting the results into the toDoTask state. While I managed to print my results on screen, they do not show on the console (shows an empty array like the initial value). And when I try to add the todoTask state as a dependency (to check the changes, when I add new tasks), the loop goes infinite. I don't know what is the problem actually, here is the code:
function App() {
const [todoTask, setTodoTask] = useState([]);
const [web3, setWeb3] = useState(undefined);
const [accounts, setAccounts] = useState(undefined);
const [contract, setContract] = useState(undefined);
const [taskCount, setTaskCount] = useState(0);
// HERE I HAVE HAD ANOTHER EFFECT HOOK TO CONNECT BLOCKCHAIN, I'VE REMOVED IT FOR SIMPLICITY
useEffect(() => {
const todoInit = async () => {
const taskCount = await contract.methods.taskCount().call();
setTaskCount(taskCount);
for (var i = 1; i <= taskCount; i++) {
const task = await contract.methods.tasks(i).call();
setTodoTask(prevArray => [...prevArray, task.content]); // task is an object, i'm getting the content(text basically)
}
console.log(taskCount); // This works fine
console.log(todoTask); // This returns an empty array
}
if(typeof web3 !== 'undefined' && typeof accounts !== 'undefined' && typeof contract !== 'undefined') {
todoInit();
}
}, [web3, accounts, contract])
You can't log a state variable just setted because setTodoTask
is async.
Much better use another useEffect
:
useEffect(() => {
console.log(todoTask);
}, [todoTask]);
This should log the very last value of todoTask
.
Note: the fact that console.log(taskCount);
works fine it's just a case (maybe due to the fact that for
takes a lot of time and setTaskCount
will be resolved before).