I am sending an array named tags as props and i want to assign it in initial states so that those array elements should be displayed. using this code they are displayed properly but i am unable to edit them. when i click cross it gets deleted but after sometime it displays again. Seems like setState in handelClose method is not working.
import React from 'react';
import ReactDOM from 'react-dom';
import { Tag, Input, Tooltip, Button } from 'antd';
class EditableTagGroup extends React.Component {
constructor(props) {
super(props);
this.state = {
tags: [],
inputVisible: false,
inputValue: '',
};
}
handleClose = (removedTag) => {
// debugger;
const tags = this.state.tags.filter(tag => tag !== removedTag);
console.log(tags);
// debugger;
this.setState({ tags: tags });
}
showInput = () => {
this.setState({ inputVisible: true }, () => this.input.focus());
}
handleInputChange = (e) => {
this.setState({ inputValue: e.target.value });
}
handleInputConfirm = () => {
const state = this.state;
const inputValue = state.inputValue;
let tags = state.tags;
if (inputValue && tags.indexOf(inputValue) === -1) {
tags = [...tags, inputValue];
}
console.log(tags);
this.setState({
tags,
inputVisible: false,
inputValue: '',
});
this.props.onSelect(tags);
}
// componentDidUpdate(prevProps, prevState) {
// this.setState({tags: this.props.tags})
// }
componentDidUpdate(prevProps, prevState) {
// debugger;
if (this.state.tags !== this.props.tags) {
this.setState({tags: this.props.tags})
}
}
saveInputRef = input => this.input = input
render() {
const {tags , inputVisible, inputValue } = this.state;
return (
<div>
{tags.map((tag, index) => {
const isLongTag = tag.length > 20;
const tagElem = (
<Tag key={tag} closable={index !== -1} afterClose={() => this.handleClose(tag)}>
{isLongTag ? `${tag.slice(0, 20)}...` : tag}
</Tag>
);
return isLongTag ? <Tooltip title={tag} key={tag}>{tagElem}</Tooltip> : tagElem;
})}
{inputVisible && (
<Input
ref={this.saveInputRef}
type="text"
size="small"
style={{ width: 78 }}
value={inputValue}
onChange={this.handleInputChange}
onBlur={this.handleInputConfirm}
onPressEnter={this.handleInputConfirm}
/>
)}
{!inputVisible && <Button size="small" type="dashed" onClick={this.showInput}>+ New Tag</Button>}
</div>
);
}
}
export default EditableTagGroup
The problem is that, you are saving and using the props in the local state and then modifying those, however everytime the component updates, you are setting the state back to the props.
What you need to do is to not maintain, the props in state but rather directly modifying it, by passing a handler from the parent to update the props.
See this answer on how to pass and update data in parent
How to pass data from child component to its parent in ReactJS?