I am having an issue with my recipe project. In this section
users can add their recipe steps. The user clicks on the plus button to add a textarea
to write a new step and clicks on the minus button to remove a step.
The plus button works fine and adds a textarea
when clicked, however, the issue I am having is that when the user removes a step the state does not update until the user clicks the plus button again. I am not sure why the minus button does not update straight away like the plus button.
These are the add and remove functions
type Textbox = {
readonly id: string;
index: number;
};
const [textboxes, setTextboxes] = useState<Textbox[]>([]);
const handleAddTextBox = () => {
const textbox = {
id: uniqid(),
index: textboxes?.length + 1,
};
const allTextBoxes = [...textboxes, textbox];
setTextboxes(allTextBoxes);
};
const handleRemoveTextBox = () => {
if (textboxes.length <= 1) {
alert("You need at least one step. Try being more descriptive.");
} else {
textboxes.pop();
}
};
This is where I implement them
<section className={`${styles.section5} ${styles.section}`}>
<div className={styles.field}>
<h1 className={styles.label}>instructions</h1>
<div className={styles["step-list"]}>
{textboxes.map((box: { id: string; index: number }) => (
<div className={styles.step} key={box.id}>
<label htmlFor={box.id} className={styles.index}>
step {box.index}
</label>
<textarea
name={box.id}
id={box.id}
cols={100}
rows={3}
className={styles.textbox}
ref={instructionRef}
></textarea>
</div>
))}
</div>
{/* Add textbox button */}
<button
className={`${styles.icon} ${styles.add}`}
onClick={handleAddTextBox}
type="button"
>
<i className="fa-solid fa-plus"></i>
</button>
{/* Remove textbox button */}
<button
className={`${styles.icon} ${styles.remove}`}
onClick={handleRemoveTextBox}
type="button"
>
<i className="fa-solid fa-minus"></i>
</button>
</div>
</section>
I have also included a link to my GitHub repo where you can view the rest of my source code incase this is not enough or something else I am doing is affecting my problem. Go to src/components/Post/PostForm.tsx
to view the relevant code.
source-code
2
Answers
textboxes
is a reference for react’s signal created byuseState()
those. It is a mutable array, but react does not have two-way data binding like Angular.Once you modified the array, you have to call
setTextboxes(newArray)
to update the UI.You need to
setTextboxes
inside yourhandleRemoveTextBox
function in order to update the state.