Draggables 在拖动时组合在一起
Draggables grouped together on drag
我正在使用 react-beautiful-dnd 库来为列表启用拖放功能,但我在拖放元素时遇到了问题。有时一些可拖动对象组合在一起,我不能在它们之间放置任何东西。看起来所有索引都是唯一的。为什么这些项目被组合在一起?任何帮助将不胜感激。
Link to image of drag behavior
这些是我在 DragDropContext 中使用的三个 React 组件的渲染方法
Cookbook.js
...
render(){
console.log("rerendering cookbook");
let cookbook;
// choose which cookbook to use
if (this.state.searchbarValue === ''){
cookbook = this.state.cookbook;
} else {
cookbook = this.state.filteredCookbook;
}
return (
<div className="App">
<Header />
<div id="dialogWindow">
{this.state.showAddChapter && <AddChapterDialog showAddChapterDialog={this.displayAddChapterWindow} rerenderCookbook={this.rerenderCookbook}/>}
{this.state.showAddRecipe && <AddRecipeDialog showAddRecipeDialog={this.displayAddRecipeWindow} rerenderCookbook={this.rerenderCookbook}/>}
</div>
<div id="customContextWindow">
{this.state.showContextMenu && <CustomContextMenu showContextMenu={this.displayContextMenu} renameItem={(bool) => {console.log(bool); this.displayRenameDialog(bool)}} deleteItem={this.displayDeleteDialog}/>}
</div>
<div id="smallDialogWindow">
{this.state.showRename && <RenameChapterRecipeDialog showRenameChapterRecipeDialog={this.displayRenameDialog} itemTypeToModify={this.state.itemTypeToModify} textToModify={this.state.textToModify} recipeChapter={this.state.recipeChapter} rerenderCookbook={this.rerenderCookbook} />}
{this.state.showDelete && <DeleteChapterRecipeDialog showDeleteChapterRecipeDialog={this.displayDeleteDialog} itemTypeToDelete={this.state.itemTypeToModify} textToDelete={this.state.textToModify} recipeChapter={this.state.recipeChapter} rerenderCookbook={this.rerenderCookbook} />}
</div>
<input type="text" id="search-bar" placeholder="Search recipes" value={this.state.searchbarValue} onChange={this.handleSearchBarChange}></input>
<div id="cookbook">
<DragDropContext onDragEnd={this.handleOnDragEnd}>
{ cookbook.length > 0 &&
<ul>
{ cookbook.map((chapter, index) =>
<Chapter name={chapter.chapterName} recipes={chapter.recipes} rightClick={ (event)=>{this.showMenu(event);} } index={index}/>
)}
</ul>
}
{ (cookbook.length === 0 && this.state.searchbarValue !== '') &&
<div id="empty-search-results">No recipes found</div>
}
</DragDropContext>
</div>
{!this.state.cookiesAccepted && <CookiePopupWarning accepted={this.state.cookiesAccepted} showCookiePopupWarning={(bool) => {this.showCookiePopupWarning(bool)}}/>}
<div className="add-bar flex-container">
<div id="add-chapter" className="add-btn" onClick={() => this.displayAddChapterWindow(true)}><div className="add-sign">+</div>Add chapter</div><div id="add-recipe" className="add-btn" onClick={()=>{ this.displayAddRecipeWindow(true) }}><div className="add-sign">+</div>Add recipe</div>
</div>
</div>
);
}
Chapter.js
...
render(){
let chapterExpanded;
if (this.props.recipes.length === 0){ // if no recipes, don't show toggle
chapterExpanded="none";
} else { // otherwise expand chapter
chapterExpanded="true";
}
return (
<Droppable droppableId={this.props.name}>
{(provided) => (
<div {...provided.droppableProps} ref={provided.innerRef} className="droppable-div" >
<li itemType="chapter" ref={this.chapterRef} chapterExpanded={chapterExpanded} onClick={()=>{this.toggleChapter();}} onContextMenu={(event)=>{this.props.rightClick(event); event.preventDefault();}} >{this.props.name}</li>
<ul ref={this.recipesRef} chapterOpen="true">
{this.props.recipes.map((recipe, index) =>
<Recipe content={recipe} key={recipe._id} chapter={this.props.name} index={`${index}`} sendRightClick={(event)=>{this.props.rightClick(event); event.preventDefault();}}/>
)}
{provided.placeholder}
</ul>
</div>
)}
</Droppable>
);
}
Recipe.js
...
render(){
let chapter = this.props.chapter;
let recipeId = this.props.content.nameId;
return (
<Draggable key={recipeId} draggableId={recipeId} index={this.props.index}>
{(provided)=>(
<div className='recipe' ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
<div>
<li recipeType={this.props.content.method} chapterName={chapter} link={this.recipe.recipeLink} itemType="recipe" onClick={()=>{this.displayRecipe()}} onContextMenu={(event)=>{this.props.sendRightClick(event)}}>{this.recipe.name}</li>
<img className="recipe-icon" src={notesImg} onClick={()=>{this.showNotes()}}/>
</div>
<textarea className="cookbook-notes" notesOpen={this.state.notesOpen} disabled={this.state.notesDisabled} value={this.state.notes} onChange={(event)=>{this.accessNotes.updateNotes(event, chapter, recipeId); this.setState({notes: event.target.value});}}></textarea>
</div>
)}
</Draggable>
);
}
唉,我是个白痴,把索引传错给Recipe组件了。它应该是 index = { index } 而不是 index = { ${index} }
我正在使用 react-beautiful-dnd 库来为列表启用拖放功能,但我在拖放元素时遇到了问题。有时一些可拖动对象组合在一起,我不能在它们之间放置任何东西。看起来所有索引都是唯一的。为什么这些项目被组合在一起?任何帮助将不胜感激。
Link to image of drag behavior
这些是我在 DragDropContext 中使用的三个 React 组件的渲染方法
Cookbook.js
...
render(){
console.log("rerendering cookbook");
let cookbook;
// choose which cookbook to use
if (this.state.searchbarValue === ''){
cookbook = this.state.cookbook;
} else {
cookbook = this.state.filteredCookbook;
}
return (
<div className="App">
<Header />
<div id="dialogWindow">
{this.state.showAddChapter && <AddChapterDialog showAddChapterDialog={this.displayAddChapterWindow} rerenderCookbook={this.rerenderCookbook}/>}
{this.state.showAddRecipe && <AddRecipeDialog showAddRecipeDialog={this.displayAddRecipeWindow} rerenderCookbook={this.rerenderCookbook}/>}
</div>
<div id="customContextWindow">
{this.state.showContextMenu && <CustomContextMenu showContextMenu={this.displayContextMenu} renameItem={(bool) => {console.log(bool); this.displayRenameDialog(bool)}} deleteItem={this.displayDeleteDialog}/>}
</div>
<div id="smallDialogWindow">
{this.state.showRename && <RenameChapterRecipeDialog showRenameChapterRecipeDialog={this.displayRenameDialog} itemTypeToModify={this.state.itemTypeToModify} textToModify={this.state.textToModify} recipeChapter={this.state.recipeChapter} rerenderCookbook={this.rerenderCookbook} />}
{this.state.showDelete && <DeleteChapterRecipeDialog showDeleteChapterRecipeDialog={this.displayDeleteDialog} itemTypeToDelete={this.state.itemTypeToModify} textToDelete={this.state.textToModify} recipeChapter={this.state.recipeChapter} rerenderCookbook={this.rerenderCookbook} />}
</div>
<input type="text" id="search-bar" placeholder="Search recipes" value={this.state.searchbarValue} onChange={this.handleSearchBarChange}></input>
<div id="cookbook">
<DragDropContext onDragEnd={this.handleOnDragEnd}>
{ cookbook.length > 0 &&
<ul>
{ cookbook.map((chapter, index) =>
<Chapter name={chapter.chapterName} recipes={chapter.recipes} rightClick={ (event)=>{this.showMenu(event);} } index={index}/>
)}
</ul>
}
{ (cookbook.length === 0 && this.state.searchbarValue !== '') &&
<div id="empty-search-results">No recipes found</div>
}
</DragDropContext>
</div>
{!this.state.cookiesAccepted && <CookiePopupWarning accepted={this.state.cookiesAccepted} showCookiePopupWarning={(bool) => {this.showCookiePopupWarning(bool)}}/>}
<div className="add-bar flex-container">
<div id="add-chapter" className="add-btn" onClick={() => this.displayAddChapterWindow(true)}><div className="add-sign">+</div>Add chapter</div><div id="add-recipe" className="add-btn" onClick={()=>{ this.displayAddRecipeWindow(true) }}><div className="add-sign">+</div>Add recipe</div>
</div>
</div>
);
}
Chapter.js
...
render(){
let chapterExpanded;
if (this.props.recipes.length === 0){ // if no recipes, don't show toggle
chapterExpanded="none";
} else { // otherwise expand chapter
chapterExpanded="true";
}
return (
<Droppable droppableId={this.props.name}>
{(provided) => (
<div {...provided.droppableProps} ref={provided.innerRef} className="droppable-div" >
<li itemType="chapter" ref={this.chapterRef} chapterExpanded={chapterExpanded} onClick={()=>{this.toggleChapter();}} onContextMenu={(event)=>{this.props.rightClick(event); event.preventDefault();}} >{this.props.name}</li>
<ul ref={this.recipesRef} chapterOpen="true">
{this.props.recipes.map((recipe, index) =>
<Recipe content={recipe} key={recipe._id} chapter={this.props.name} index={`${index}`} sendRightClick={(event)=>{this.props.rightClick(event); event.preventDefault();}}/>
)}
{provided.placeholder}
</ul>
</div>
)}
</Droppable>
);
}
Recipe.js
...
render(){
let chapter = this.props.chapter;
let recipeId = this.props.content.nameId;
return (
<Draggable key={recipeId} draggableId={recipeId} index={this.props.index}>
{(provided)=>(
<div className='recipe' ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
<div>
<li recipeType={this.props.content.method} chapterName={chapter} link={this.recipe.recipeLink} itemType="recipe" onClick={()=>{this.displayRecipe()}} onContextMenu={(event)=>{this.props.sendRightClick(event)}}>{this.recipe.name}</li>
<img className="recipe-icon" src={notesImg} onClick={()=>{this.showNotes()}}/>
</div>
<textarea className="cookbook-notes" notesOpen={this.state.notesOpen} disabled={this.state.notesDisabled} value={this.state.notes} onChange={(event)=>{this.accessNotes.updateNotes(event, chapter, recipeId); this.setState({notes: event.target.value});}}></textarea>
</div>
)}
</Draggable>
);
}
唉,我是个白痴,把索引传错给Recipe组件了。它应该是 index = { index } 而不是 index = { ${index} }