如何解决ReactJS-页面重新渲染,但是一个组件保持不变 美丽的拖放
我遇到一个非常奇怪的问题,页面上只有一个组件没有被刷新,而我只是想不通为什么。
以下是该问题的简短视频:
according to the DenseVector documentations
请注意,当我单击“确认”时,问题字符串将如何更改(应如此),但是拖放窗口的卡片保持不变。它一直显示问题名称“ yooo”和答案“ abc,def”,但这仅对第一个问题有效。
我对ReactJS还是比较陌生,所以这里可能有一些我不熟悉的功能?据我所知,DragAndDrop应该完全与下一个问题一起重新渲染。当前,构造函数不再被调用,它以某种方式保存了最后一个问题的数据。
此页面的呈现。 DragAndDrop在这里被调用。在confirm()中,将currentQuestion设置为下一个问题。
return (
<div>
<h3>{currentQuestion.question}</h3>
<DragAndDrop
answers={currentQuestion.answers}
/>
<Button onClick={() => confirm()}>Confirm</Button>
</div>
);
整个DragAndDrop.js 抱歉,代码壁与Beautiful-DND https://i.gyazo.com/45e229b0867c37e48a18da7a55afb522.mp4
中的示例代码几乎相同/* eslint-disable no-console */
/* eslint-disable react/prop-types */
import React,{ Component } from "react";
import { DragDropContext,Droppable,Draggable } from "react-beautiful-dnd";
// STYLING
const grid = 8;
const getItemStyle = (isDragging,draggableStyle) => ({
// some basic styles to make the items look a bit nicer
userSelect: "none",padding: grid * 2,margin: `0 0 ${grid}px 0`,// change background colour if dragging
background: isDragging ? "cyan" : "white",// styles we need to apply on draggables
...draggableStyle,});
const getListStyle = (isDraggingOver) => ({
background: isDraggingOver ? "lightblue" : "lightgrey",padding: grid,width: "100%",});
// a little function to help us with reordering the result
const reorder = (list,startIndex,endindex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex,1);
result.splice(endindex,removed);
return result;
};
export default class DragAndDrop extends Component {
constructor(props) {
super(props);
this.state = {
items: props.answers,};
this.onDragEnd = this.onDragEnd.bind(this);
console.log("Answers & items");
console.log(this.props.answers);
console.log(this.state.items);
}
onDragEnd(result) {
// dropped outside list
if (!result.destination) {
return;
}
const items = reorder(
this.state.items,result.source.index,result.destination.index
);
this.setState({
items,});
}
render() {
return (
<DragDropContext onDragEnd={this.onDragEnd}>
<Droppable droppableId="droppable">
{(provided,snapshot) => (
<div
{...provided.droppableProps}
ref={provided.innerRef}
style={getListStyle(snapshot.isDraggingOver)}
>
{this.state.items.map((item,index) => (
<Draggable
key={item.id}
draggableId={item.id.toString()}
index={index}
>
{(provided,snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,provided.draggableProps.style
)}
>
{
item.answer +
" index: " +
index +
" ordering:" +
item.ordering /*CONTENT OF CARD*/
}
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
);
}
}
解决方法
我认为问题出在constructor
的这一行:
this.state = {
items: props.answers,};
在构造函数中像这样设置items
意味着您将忽略父组件对props
的以下更新!如果您选中official documentation,他们会对此提出警告。
避免将道具复制到状态中!这是一个常见的错误:
问题在于,这既不必要(您可以直接使用this.props.color),又会产生错误(对color prop的更新不会反映在状态中)。
仅当您有意忽略道具更新时才使用此模式。在这种情况下,将prop重命名为initialColor或defaultColor是有意义的。然后,您可以在必要时通过更改其键来强制组件“重置”其内部状态。
如果要依赖props
的值并相应地更改状态,则可以使用static getDerivedStateFromProps()
这里是working example using a class-based component,这只是将组件与static getDerivedStateFromProps()
一起使用的概念证明(不推荐使用!)。我添加了一些虚拟数据,这些数据使用与父组件中提供的结构相同的结构,当您单击“确认”时,该结构会发生变化。另外,这是working example using hooks的工作方式,它使用了useState
和useEffect
钩子。
props.answers
由父组件控制并确认功能。您的DragAndDrop
组件仅将props设置为最初在构造函数中声明的状态。不知道props
何时会被更改,就像您第一次在构造函数中将props
设置为state
一样。您可以通过以下多种方式模拟道具更改:
- 用道具更改模拟状态更改
...
constructor(props) {
this.state = {items:props.answers}
...
}
componentDidUpdate(prevProps,PrevState) {
if (this.props.answers && this.props.answers !== prevProps.answers) {
this.setState({ items: this.props.answers });
}
}
-
直接使用道具,构造函数中没有状态,也没有使用
DragAndDrop
组件中的任何地方 -
移动道具并
confirm
直接在您的DragAndDrop
组件中
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。