如何更改已复制元素的ID

时间:2019-06-24 15:39:26

标签: javascript reactjs drag-and-drop

我尝试用react-smooth-dnd创建dnd编辑器。我有2个容器:第一个是带有元素的工具栏,第二个是编辑器。 每个元素都有以下结构:

{
 id: shortid.generate(),
 type: 'TextElement',
 options: {
    text: 'Text',
    style: {
       padding: '10px 0 10px 15px'
    },
    isShowToolBar: false
 }
}

当我尝试将元素从第一个容器复制到第二个容器时,我想更改当前元素的id,但是当我尝试使用onDrop回调时,我只能更改{{1 }}两个容器的每个元素。

如何仅更改id当前元素?

我的第一个(工具栏)容器是:

id

还有我的第二个容器(编辑器):

<Container
  groupName="1"
  behaviour="copy"
  getChildPayload={i => this.state.items[i]}
>
  {
    this.state.items.map((element,i) => {
      const component = createComponent(element, TYPE_TOOLBAR);
      return (
        <Draggable
          key={i}
          style={{display: 'inline-block', padding: '10px'}}
          className="col-xl-4 col-lg-4 col-md-4 col-sm-12 col-12"
       >
         {component}
       </Draggable>
      );
    })
  }
</Container>

2 个答案:

答案 0 :(得分:1)

我认为您正在寻找的东西是reactCloneElement,它允许您使用组件并更改其道具。 请小心使用此功能,它会将克隆的元素的引用保留下来。

我在这里尝试一种可能的实现方式

const applyDrag = e => {

 const {items} = this.state
 // you get your element
 const element = e. ???? 

 // Then you recreate it and changing his id 
 const item = React.cloneElement(
  element,
  {
   id: shortid.generate(),
   ...element.props,
  },
)

 this.setState({items: items.length > 0 ? items.concat(item) : [].concat(item)})
}

<Container
    groupName="1"
    getChildPayload={i => this.state.items[i]}
    onDrop={this.applyDrag(e)}
    lockAxis="y"
    dragHandleSelector=".element-drag-handler"
>
    {
        this.state.items.map((element, i) => {
            const component = createComponent(
                element,
                TYPE_EDITOR,
                this.elementToolBarHandler
            );

            return (
                <Draggable key={i}>
                    {component}
                </Draggable>
            );
        })
    }

答案 1 :(得分:0)

好吧,我尝试了几种方法,如果您不希望使用reactCloneElement克隆元素,则可以执行以下操作。

在我的第一个容器(工具栏)中,创建了一个onDragStart回调:

onDragStart={e => this.onDragStart(e)}

函数实现:

updateId(element) {
    let index = this.state.items.findIndex(x => x.id === element.id);
    if (index === -1) index = 1;
    this.setState(update(this.state, {
        items: {
            [index]: {
                $merge: {
                    id: shortid.generate()
                }
            }
        }
    }));
}

onDragStart({payload}) {
    this.updateId(payload);
}