I am new to React. I am working on a simple project where clicking a +/- button will increment or decrement the date by one day but am having trouble getting the two functions to work for a click event, please see code below. I am not sure why error message 'newDate is undefined' keeps coming up when the variable is defined and the state has been set. If anybody has any solutions please let me know. Thanks. *** N.b I am just working on the 'minus' button for now.
import React from "react";
import ReactDOM from "react-dom/client";
import { useState } from "react";
function App() {
const date = new Date("june 21 2027");
const [newDate, setNewDate] = useState(date);
const [count, setCount] = useState(1);
return (
<div>
{/* <div>
<button>-</button>
<span>Step : Step 1</span>
<button>+</button>
</div> */}
<div>
<button
className={"minus"}
id={1}
onClick={function () {
setCount(function (c) {
return c - 1;
});
setNewDate(function (d) {
d.setDate(date.getDate() - count);
return;
});
}}
>
-
</button>
<span>Count : {count}</span>
<button
className={"plus"}
id={2}
onClick={function () {
return setCount(function (c) {
return c + 1;
});
}}
>
+
</button>
</div>
<span>Today is {`${newDate.toDateString()}`}</span>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
I have tried returning the setNewDate function into the setCount function but that didn't work.
As you told that you are a beginner, ill give a bit descriptive answer. Feel free to talk back if you prefer a shorter response.
Overall, analyzing your code I found out few issues. But still no need to worry. As a beginner, you have already climbed the hardest step
As I got, here's what you are going to do.
Updating the count and based on the value of the count you are updating the date, which means you are accessing the initial date when updating.
When we consider the end result updating the date with step of 1, this is not the best approach, but let's stick with this approach because there's a lot to learn.
First of all, state updates are not immediate. This is a thing that you need to keep in mind.
You are doing setCount(...)
and setNewDate(...)
but as I told you state updates are not immediate you are still accessing the previous value of the count
You're calling setNewDate
with no return value (return;
), which breaks the state update.
You're modifying the original date
object (date.setDate()
), which may lead to unexpected side effects.
This is my plan for fixing the code. In the onClick function I'm calling the setCount in the setCount I'm caching the updated count, also I'm caching the initialDate as a Date
object which is date
according to your code. On the cached date I'm calling the pre-defined setDate
and I'm calling the predefined getDate
on intial date and adding the updated count value to that date. Now I'm updating the date which is newDate
according to your code by calling the setNewDate
and passing the cached updatedDate wich is now updated. Finally I'm returning the updated count so that it uppdates the count state variable.
If you still want the fixed version of the function to be triggered onClick I'll paste it down below.
Just so you know () => {}
this is the arrow function syntax which comes under JS ES6+ features.
onClick={() => {
setCount((c) => {
const newCount = c - 1;
const updatedDate = new Date(baseDate);
updatedDate.setDate(baseDate.getDate() + newCount);
setNewDate(updatedDate);
return newCount;
});
}}