I'm trying to update the state of an array with React Hooks, using an input received from a child ponent.
This is the code for the array I'm trying to update (in my App.js file):
const [results, setResults] = useState([]);
const submitHandler = newResult => {
const newArray = [...results, newResult];
setResults(newArray);
console.log(newArray);
console.log(results);
}
The newArray
is updated and logged properly, with all the items that are submitted through the child ponent. But the state of results
is never updated, and it always logs an empty array. It should be noted that other useState hooks in my app are working properly, only the one I'm using for this array isn't working. Does anyone know what could be wrong and how can it be fixed?
If it helps, this is the code that submits the items from the child ponent (Shorten.js) - these hooks are working perfectly fine:
const [urlInput, setUrlInput] = useState("");
const [error, setError] = useState(false);
const changeHandler = event => {
setUrlInput(event.target.value);
}
const submitHandler = event => {
event.preventDefault();
if (urlInput === "") {
setError(true);
}
else {
setError(false);
axios.post("/api/links/", {
url: urlInput
})
.then(response => {
const newResult = {
original: urlInput,
shortened: "/" + response.data.hashid
}
props.submit(newResult);
})
setUrlInput("");
}
}
I'm trying to update the state of an array with React Hooks, using an input received from a child ponent.
This is the code for the array I'm trying to update (in my App.js file):
const [results, setResults] = useState([]);
const submitHandler = newResult => {
const newArray = [...results, newResult];
setResults(newArray);
console.log(newArray);
console.log(results);
}
The newArray
is updated and logged properly, with all the items that are submitted through the child ponent. But the state of results
is never updated, and it always logs an empty array. It should be noted that other useState hooks in my app are working properly, only the one I'm using for this array isn't working. Does anyone know what could be wrong and how can it be fixed?
If it helps, this is the code that submits the items from the child ponent (Shorten.js) - these hooks are working perfectly fine:
const [urlInput, setUrlInput] = useState("");
const [error, setError] = useState(false);
const changeHandler = event => {
setUrlInput(event.target.value);
}
const submitHandler = event => {
event.preventDefault();
if (urlInput === "") {
setError(true);
}
else {
setError(false);
axios.post("https://rel.ink/api/links/", {
url: urlInput
})
.then(response => {
const newResult = {
original: urlInput,
shortened: "https://rel.ink/" + response.data.hashid
}
props.submit(newResult);
})
setUrlInput("");
}
}
Share
Improve this question
asked Jul 3, 2020 at 12:48
Yinon HeverYinon Hever
491 gold badge1 silver badge6 bronze badges
1
- Duplicate of useState set method not reflecting change immediately – Guy Incognito Commented Jul 3, 2020 at 12:52
1 Answer
Reset to default 6In your example, you cannot guarantee the results
state has been updated at the point of your console.log(results)
. This is because the React state update as asynchronous and applied in batches under the hood.
If you had your console.log
call under const [result, setResults] = useState([])
then it will get called on every render pass, and therefore you should see the updated value logged out once the setState
function has applied your new state.
For example:
const [results, setResults] = useState([]);
console.log(results);
const submitHandler = newResult => {
const newArray = [...results, newResult];
setResults(newArray);
console.log(newArray);
}
should log your new state on the next render pass.
You could also put your console.log
in a useEffect
which will let you know for sure that React knows your results
have changed.
const [results, setResults] = useState([]);
useEffect(() => {
console.log(results);
}, [results]);
const submitHandler = newResult => {
const newArray = [...results, newResult];
setResults(newArray);
console.log(newArray);
}
This means your console.log(results)
will only be called when results
changed, rather then on every render.