我想构建一个页面,该页面具有不确定数量的元素(<Rnd></Rnd>
),可以使用react-rnd插件拖动并调整其大小。用户最终将能够从DOM中动态添加/删除这些元素。
使用elementId
的数组我在页面上输出6个元素,但是当我将它们拖动到它们周围时它们一起移动并且不是独立的,这在使用react-dev-tools检查它们时得到确认铬。
我认为这是因为他们共享相同的状态,但我如何给他们自己的?
我已经分配了一把钥匙,但我不知道接下来要转向哪里。
我的组件如下所示:
import React, { Component } from 'react';
import Rnd from 'react-rnd';
import styled from 'styled-components';
import './BuildTemplate.css';
class BuildTemplate extends Component {
constructor(props) {
super(props);
this.state = {
width: 200,
height: 200,
x: 10,
y: 10,
};
}
render() {
const HandleClasses = {
bottomLeft: 'corner-handle bottom-left',
bottomRight: 'corner-handle bottom-right',
topLeft: 'corner-handle top-left',
topRight: 'corner-handle top-right',
};
function LibraryElements(props) {
const {
elementIds, className, size, position, resizeHandleClasses, bounds, onDragStop, onResize,
} = props;
const elementList = elementIds.map(elementId => (
<Rnd
key={elementId.toString()}
className={`${className} ${elementId.toString()}`}
size={size}
position={position}
resizeHandleClasses={resizeHandleClasses}
bounds={bounds}
onDragStop={onDragStop}
onResize={onResize}
>{elementId}
</Rnd>));
return (
elementList
);
}
const elementIds = [1, 2, 3, 4, 5, 6];
return (
<div>
<MasterTemplate>
<LibraryElements
elementIds={elementIds}
className="library-element"
size={{ width: this.state.width, height: this.state.height }}
position={{ x: this.state.x, y: this.state.y }}
resizeHandleClasses={HandleClasses}
bounds="parent"
onDragStop={(e, d) => { this.setState({ x: d.x, y: d.y }); }}
onResize={(e, direction, ref, delta, position) => {
this.setState({
width: ref.offsetWidth,
height: ref.offsetHeight,
...position,
});
}}
>Test
</LibraryElements>
</MasterTemplate>
</div>
);
}
}
export default BuildTemplate;
const MasterTemplate = styled.div`
width: 900px;
height: 500px;
border: 1px solid #ccc;
position: relative;
display: block;
margin: 30px;
background: #fff;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
`;
答案 0 :(得分:1)
访问相同的状态数据会使Rnd
组件具有相同的行为。给他们不同的ID对此无能为力。
我建议您删除elementIds
;相反,使用位置数组初始化状态,每个生成的Rnd
组件将仅更新该数组中的一个项目。
class BuildTemplate extends Component {
constructor(props) {
super(props);
this.state = {
elements: Array.from({ length: 6 }, () => ({ x : 10, y: 200, width: 200, height: 200 }))
};
}
render() {
const HandleClasses = {
bottomLeft: 'corner-handle bottom-left',
bottomRight: 'corner-handle bottom-right',
topLeft: 'corner-handle top-left',
topRight: 'corner-handle top-right',
};
function LibraryElements(props) {
const {
initialData, className, resizeHandleClasses, bounds, onDragStop, onResize,
} = props;
const elementList = initialData.map((item, index) => (
<Rnd
key={(index + 1).toString()}
className={`${className} ${(index + 1).toString()}`}
size={{ width: item.width, height: item.height}}
position={{ x: item.x, y: item.y }}
resizeHandleClasses={resizeHandleClasses}
bounds={bounds}
onDragStop={(...args) => onDragStop(index, ...args)}
onResize={(...args) => onResize(index, ...args)}>
{(index + 1)}
</Rnd>));
return (
elementList
);
}
return (
<div>
<MasterTemplate>
<LibraryElements
initialData={this.state.elements}
className="library-element"
size={{ width: this.state.width, height: this.state.height }}
resizeHandleClasses={HandleClasses}
bounds="parent"
onDragStop={(index, e, d) => {
let elements = this.state.elements;
elements[index] = {
...elements[index],
x: d.x,
y: d.y
};
this.setState({
elements: elements
})
}}
onResize={(index, e, direction, ref, delta, position) => {
let elements = this.state.elements;
elements[index] = {
...elements[index],
width: ref.offsetWidth,
height: ref.offsetHeight
};
this.setState({
elements: elements
})
}}
>Test
</LibraryElements>
</MasterTemplate>
</div>
);
}
}