I want to append a div with two text fields whenever the user clicks a button.
I'm trying to do so by using useState and pushing the new JSX element to an array.
But I'm having a couple of problems:
- When clicking the button the first time, instead of the new elements in the DOM, I see the number 2, which seems to be the length of the array.
- By clicking the button again, I get the error
linksArray.push is not a function.
function LinkFieldsSet() {
return (
<div>
<TextField label="Text" />
<TextField label="URL" />
</div>
)
}
function Links() {
const [{linksArray, keyNum}, setState] = React.useState({
linksArray: [<LinkFieldsSet key={1} />],
keyNum: 1,
});
const handleAddClick = () => {
setState({
keyNum: keyNum 1,
linksArray: linksArray.push(<LinkFieldsSet key={keyNum} />)
});
};
return (
<div>
{linksArray}
<AddRowsButton action={handleAddClick} />
</div>
)
}
CodePudding user response:
The line linksArray: linksArray.push(<LinkFieldsSet key={keyNum} /> pushes the element to linksArray and returns the new length of the array. So after this line your linksArray is a number.
Also, {linksArray} jsx binding is a bit incorrect as for me.
Try this:
function Links() {
const [{ linksArray, keyNum }, setState] = React.useState({
linksArray: [<LinkFieldsSet key={1} />],
keyNum: 1
});
const handleAddClick = () => {
linksArray.push(<LinkFieldsSet key={keyNum 1} />);
setState({
keyNum: keyNum 1,
linksArray: linksArray
});
};
return (
<div>
{linksArray.map((x) => x)}
<AddRowsButton action={handleAddClick} />
</div>
);
}
CodePudding user response:
Problem seems to be with handleAddClick method. Array.push would not return an Array, use Array.concat instead. Update handleAddClick as below,
const handleAddClick = () => {
const newKeyNum = keyNum 1;
setState({
keyNum: newKeyNum,
linksArray: linksArray.concat(<LinkFieldsSet key={newKeyNum} />)
});
};
