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} />)
});
};