Как я могу изменить идентификатор скопированного элемента - PullRequest
0 голосов
/ 24 июня 2019

Я пытаюсь создать dnd-редактор с response-smooth-dnd. У меня есть 2 контейнера: первый - это панель инструментов с элементами, второй - редактор. Каждый элемент имеет следующую структуру:

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

Когда я пытаюсь скопировать элемент из первого контейнера во второй, я хочу изменить id текущего элемента, но когда я пытаюсь сделать это с помощью обратного вызова onDrop, я могу изменить только 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>

И мой второй контейнер (редактор):

<Container
    groupName="1"
    getChildPayload={i => this.state.items[i]}
    onDrop={e => this.setState({
        items: applyDrag(this.state.items, 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>
            );
        })
    }
</Container>

Ответы [ 2 ]

1 голос
/ 25 июня 2019

Я думаю, что вы ищете для реагирующего элемента, он позволяет вам взять компонент и изменить его реквизиты.Будьте осторожны с этой функцией, она хранит ссылки из клонированного элемента.

Вот моя попытка возможной реализации

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>
            );
        })
    }
0 голосов
/ 25 июня 2019

Ну, я пробовал несколько способов, и если вы не хотите, чтобы элемент клонирования с 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...