Я пытаюсь добавить перетаскиваемые атрибуты к отображаемому компоненту, однако я не знаю, где именно их добавить. Таким образом, они, по крайней мере, отображаются, но массив не обновляется в OnDragEnd при удалении элемента. Компонент:
const Item = props => {
const finishedButton = <button onClick = {props.handleComplete} className = "finishedButton">✔</button>
return (
<li className = "background"
draggable
onDragStart = {props.dragStart}
onDragEnd = {props.dragEnd}
>
{finishedButton}{props.item}
</li>
и в рендере в приложении
<ul onDragOver = {e => this.dragOver(e)}>
{this.state.items.map((item, i)=> (
<Item
data-id = {i}
key = {i}
dragStart = {e => this.dragStart(e)}
dragEnd = {e => this.dragEnd(e)}
item = {item.text}
/>
))}
</ul>
Кодовое слово: https://codepen.io/Matt-dc/pen/zbYKNv





В вашем dragEnd функция this.draggedElem не определена. И поэтому prevIndex и newIndex также не определены, что приводит к тому, что data.splice возвращает старое состояние.
Я не уверен в вашей логике, но, кажется, она работает
let placeholder = document.createElement("li");
placeholder.className = "placeholder";
const Item = props => {
const finishedButton = <button onClick = {props.handleComplete} className = "finishedButton">✔</button>
return (
<li className = "background"
draggable
onDragStart = {props.dragStart}
onDragEnd = {props.dragEnd}
onDragOver = {props.dragOver}
>
{finishedButton}{props.item}
>
</li>
);
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
items: [
{id: 1, text: "clean car", complete: false},
{id: 2, text: "wash dog", complete: false},
{id: 3, text: "water plants", complete: false},
{id: 4, text: "prune shrubs", complete: false},
{id: 5, text: "tidy house", complete: false}
],
input: ""
}
this.dragStart = this.dragStart.bind(this);
this.dragOver = this.dragOver.bind(this);
this.dragEnd = this.dragEnd.bind(this);
this.handleChangeEvent = this.handleChangeEvent.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChangeEvent = e => {
this.setState({
input: e.target.value
});
}
handleSubmit = () => {
let newItem = {};
newItem.id = uuid.v4();
newItem.text = this.state.input;
newItem.complete = false;
let newItems = this.state.items.concat(newItem);
this.setState({
items: newItems,
});
this.setState({input: ''})
}
handleComplete = e => {
}
dragStart = e => {
this.draggedElem = e.target;
e.dataTransfer.setData('text/html', this.draggedElem);
}
dragOver = e => {
e.preventDefault();
//this.draggedElem.style.display = "none";
if (e.target.className === 'placeholder') return;
this.newIndex = e.target
}
dragOverItem = (id,e) => {
this.to = id;
}
dragEnd = (from,e) => {
let data = this.state.items;
let prevIndex = from;
let newIndex = this.to;
console.info(`from ${prevIndex} to ${newIndex}`)
//if (prevIndex < newIndex) newIndex --;
data.splice(newIndex, 0, data.splice(prevIndex, 1)[0]);
this.setState({ items: data });
}
render() {
return(
<div>
<input onChange = {this.handleChangeEvent} value = {this.state.input} />
<button onClick = {this.handleSubmit}>Add item</button>
<ul onDragOver = {this.dragOver}>
{this.state.items.map((item, i)=> (
<Item
data-id = {i}
key = {i}
dragOver = {this.dragOverItem.bind(this,i)}
dragStart = {e => this.dragStart(e)}
dragEnd = {this.dragEnd.bind(this, i)}
item = {item.text}
/>
))}
</ul>
<p>{this.state.input}</p>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
Как установить их обоих в этом случае: this.draggedElem = e.target; оказывается не работает...