onLayoutChange 正在从本地存储重置我的数据
onLayoutChange is resetting my data from local storage
每当我的布局发生变化时,它会将新的更改保存到本地存储并更新我的布局状态
onLayoutChange(layouts) {
saveToLS("layouts", layouts);
}
但是,刷新页面时会出现问题。布局在从本地存储中获取之前已更新,这意味着它放弃所有更改并将布局重置为默认值。下图显示了我的意思
我应该怎么做才能防止这种情况发生??我正在关注这个 guide。它正在编写指南,但不适合我,非常感谢任何帮助
这是我使用的完整代码
const originalLayouts = getFromLS("layouts") || {};
const ResponsiveReactGridLayout = WidthProvider(Responsive);
class MinMaxLayout extends React.PureComponent {
static defaultProps = {
margin:[0,0],
className:"layout",
cols: { lg: 1, md: 10 },
rowHeight: 100
};
constructor(props) {
super(props);
this.state = {
layouts: JSON.parse(JSON.stringify(originalLayouts)),
inputWidthVal: "",
inputHeightVal:"",
items: [0, 1, 2, 3, 4].map(function (i, key, list) {
return {
id: uuidV4(),
i: i.toString(),
x: i * 2,
y: 0,
w: 1,
h: 1
};
}),
charts: [0].map(function (i, key, list) {
return {
id: uuidV4(),
i: i.toString(),
x: i,
y: 0,
w: 4,
h: 3
};
}),
newCounter: 0,
chartCounter:0
};
this.onAddItem = this.onAddItem.bind(this);
this.onChartItem = this.onChartItem.bind(this);
this.onBreakpointChange = this.onBreakpointChange.bind(this);
}
createElement(el) {
const removeStyle = {
position: "absolute",
left: "11px",
top: 0,
cursor: "pointer"
};
const i = el.i;
return (
<div key={el.id} data-grid={el} >
<span
className="remove"
style={removeStyle}
onClick={this.onRemoveItem.bind(this, i)}
>
x
</span>
</div>
);
}
// this is the charts that was created when the DOM was render
createChart(el) {
const removeStyle = {
position: "absolute",
left: "11px",
top: 0,
cursor: "pointer"
};
const i = el.i;
return (
// <div key={el.id} data-grid={el} onClick={((e) => this.handleClick(e))}>
<div key={el.id} data-grid={el} className="graph">
<Newvsresturnvisitors />
<span
className="remove"
style={removeStyle}
onClick={this.onRemoveChartItem.bind(this, i)}
>
x
</span>
</div>
);
}
onAddItem() {
this.setState({
// Add a new item. It must have a unique key!
items: this.state.items.concat({
id: uuidV4(),
i: "n" + this.state.newCounter,
x: (this.state.items.length * 2) % (this.state.cols || 12),
y: Infinity, // puts it at the bottom
w: 1,
h: 1
}),
// Increment the counter to ensure key is always unique.
newCounter: this.state.newCounter + 1
});
}
onChartItem() {
this.setState({
// Add a new item. It must have a unique key!
charts: this.state.charts.concat({
id: uuidV4(),
i: "n" + this.state.chartCounter,
x: (this.state.charts.length * 2) % (this.state.cols || 12),
y: 0, // puts it at the bottom
w: 4,
h: 3
}),
// Increment the counter to ensure key is always unique.
chartCounter: this.state.chartCounter + 1
});
}
// We're using the cols coming back from this to calculate where to add new items.
onBreakpointChange(breakpoint, cols) {
this.setState({
breakpoint: breakpoint,
cols: cols
});
}
onRemoveItem(i) {
this.setState({ items: _.reject(this.state.items, { i: i }) });
}
clearAllItem = ()=>{
this.setState({ items: [], charts: [] });
}
onRemoveChartItem(i){
this.setState({ charts: _.reject(this.state.charts, { i: i }) });
}
inputCanvasDimension = e =>{
const re = /^[0-9\b]+$/;
if (e.target.value === '' || re.test(e.target.value)) {
if(e.currentTarget.className === "inputWidth"){
this.setState({inputWidthVal: e.currentTarget.value});
}else if(e.currentTarget.className === "inputHeight"){
this.setState({inputHeightVal: e.currentTarget.value});
}
}
}
setCanvasDimension = () =>{
var canvas = document.getElementById("DetailLocationContainer");
if((this.state.inputWidthVal < 1000) || (this.state.inputHeightVal < 3000)){
alert("Width should not be less than 1000 and height should not be less than 3000");
}else {
canvas.style.width= this.state.inputWidthVal + "px";
canvas.style.height= this.state.inputHeightVal + "px";
}
}
saveToLS(key, value) {
var secondObject = Object.entries(value)[1];
if (global.localStorage) {
global.localStorage.setItem(
"rgl-8",
JSON.stringify({
[key]: value
})
);
}
}
onLayoutChange(layout, layouts) {
this.saveToLS("layouts", layouts);
}
onDrop = (layout, layoutItem, _event) => {
if(_event.dataTransfer.mozSourceNode.className === "textwidget"){
this.setState({
items: this.state.items.concat({
id: uuidV4(),
i: "n" + this.state.newCounter,
x: layoutItem.x,
y: layoutItem.y,
w: 1,
h: 1
}),
newCounter: this.state.newCounter + 1
});
}else if(_event.dataTransfer.mozSourceNode.className === "chart"){
this.setState({
// Add a new item. It must have a unique key!
charts: this.state.charts.concat({
id: uuidV4(),
i: "n" + this.state.chartCounter,
x: (this.state.charts.length * 2) % (this.state.cols || 12),
y: Infinity, // puts it at the bottom
w: 5,
h: 6
}),
// Increment the counter to ensure key is always unique.
chartCounter: this.state.chartCounter + 1
});
}
};
reset = () =>{
// window.location.reload(true);
this.setState({ layouts: {} });
}
render() {
return (
<div className="container" id="container">
<div className="btn_container">
<div>
<span>Width </span>
<input className="inputWidth" value={this.state.inputWidthVal} onChange={this.inputCanvasDimension}/>
<span> Height </span>
<input className="inputHeight" value={this.state.inputHeightVal} onChange={this.inputCanvasDimension}/>
<button onClick={this.setCanvasDimension}>Apply</button>
<button onClick={this.reset}><CachedIcon style={{fontSize: '14px'}}/></button>
<button onClick={openFullscreen}><FullscreenSharpIcon style={{fontSize: '14px'}}/></button>
</div>
</div>
<button id="createItemBtn" onClick={this.onAddItem}>Add Item</button>
<button id="createChartBtn" onClick={this.onChartItem}>Add Chart</button>
<button onClick={this.clearAllItem}>Clear All</button>
<div className="widgetcontainer">
<WidgetThumbnail
className="chart"
/>
<WidgetThumbnail
className="textwidget"
/>
</div>
<div className='DetailLocationContainer' id="DetailLocationContainer" >
<ResponsiveReactGridLayout
cols={{ lg: 1, md: 10, sm: 6, xs: 4, xxs: 2 }}
rowHeight={100}
onDrop={this.onDrop}
isDroppable={true}
isBounded={true}
layouts={this.state.layouts}
onLayoutChange={(layout, layouts) =>
this.onLayoutChange(layout, layouts)
}
onBreakpointChange={this.onBreakpointChange}
{...this.props}
>
{_.map(this.state.items, (el) => this.createElement(el))}
{_.map(this.state.charts, (el) => this.createChart(el))}
</ResponsiveReactGridLayout>
</div>
</div>
);
}
}
export default MinMaxLayout;
const rootElement = document.getElementById("root");
ReactDOM.render(<MinMaxLayout />, rootElement);
这是我的 getFrinLS
export function getFromLS(key) {
let md = {};
if (global.localStorage) {
try {
md = JSON.parse(global.localStorage.getItem("rgl-8")) || {};
} catch (e) {
/*Ignore*/
}
// console.log("return value ", md[key]);
return md[key];
}
}
似乎需要增量键才能应用更新后的布局。将键值从 el.id 更改为 i
createElement(el) {
const removeStyle = {
position: "absolute",
left: "11px",
top: 0,
cursor: "pointer"
};
const i = el.i;
return (
<div key={i} data-grid={el} >
<span
className="remove"
style={removeStyle}
onClick={this.onRemoveItem.bind(this, i)}
>
x
</span>
</div>
);
}
每当我的布局发生变化时,它会将新的更改保存到本地存储并更新我的布局状态
onLayoutChange(layouts) {
saveToLS("layouts", layouts);
}
但是,刷新页面时会出现问题。布局在从本地存储中获取之前已更新,这意味着它放弃所有更改并将布局重置为默认值。下图显示了我的意思
我应该怎么做才能防止这种情况发生??我正在关注这个 guide。它正在编写指南,但不适合我,非常感谢任何帮助
这是我使用的完整代码
const originalLayouts = getFromLS("layouts") || {};
const ResponsiveReactGridLayout = WidthProvider(Responsive);
class MinMaxLayout extends React.PureComponent {
static defaultProps = {
margin:[0,0],
className:"layout",
cols: { lg: 1, md: 10 },
rowHeight: 100
};
constructor(props) {
super(props);
this.state = {
layouts: JSON.parse(JSON.stringify(originalLayouts)),
inputWidthVal: "",
inputHeightVal:"",
items: [0, 1, 2, 3, 4].map(function (i, key, list) {
return {
id: uuidV4(),
i: i.toString(),
x: i * 2,
y: 0,
w: 1,
h: 1
};
}),
charts: [0].map(function (i, key, list) {
return {
id: uuidV4(),
i: i.toString(),
x: i,
y: 0,
w: 4,
h: 3
};
}),
newCounter: 0,
chartCounter:0
};
this.onAddItem = this.onAddItem.bind(this);
this.onChartItem = this.onChartItem.bind(this);
this.onBreakpointChange = this.onBreakpointChange.bind(this);
}
createElement(el) {
const removeStyle = {
position: "absolute",
left: "11px",
top: 0,
cursor: "pointer"
};
const i = el.i;
return (
<div key={el.id} data-grid={el} >
<span
className="remove"
style={removeStyle}
onClick={this.onRemoveItem.bind(this, i)}
>
x
</span>
</div>
);
}
// this is the charts that was created when the DOM was render
createChart(el) {
const removeStyle = {
position: "absolute",
left: "11px",
top: 0,
cursor: "pointer"
};
const i = el.i;
return (
// <div key={el.id} data-grid={el} onClick={((e) => this.handleClick(e))}>
<div key={el.id} data-grid={el} className="graph">
<Newvsresturnvisitors />
<span
className="remove"
style={removeStyle}
onClick={this.onRemoveChartItem.bind(this, i)}
>
x
</span>
</div>
);
}
onAddItem() {
this.setState({
// Add a new item. It must have a unique key!
items: this.state.items.concat({
id: uuidV4(),
i: "n" + this.state.newCounter,
x: (this.state.items.length * 2) % (this.state.cols || 12),
y: Infinity, // puts it at the bottom
w: 1,
h: 1
}),
// Increment the counter to ensure key is always unique.
newCounter: this.state.newCounter + 1
});
}
onChartItem() {
this.setState({
// Add a new item. It must have a unique key!
charts: this.state.charts.concat({
id: uuidV4(),
i: "n" + this.state.chartCounter,
x: (this.state.charts.length * 2) % (this.state.cols || 12),
y: 0, // puts it at the bottom
w: 4,
h: 3
}),
// Increment the counter to ensure key is always unique.
chartCounter: this.state.chartCounter + 1
});
}
// We're using the cols coming back from this to calculate where to add new items.
onBreakpointChange(breakpoint, cols) {
this.setState({
breakpoint: breakpoint,
cols: cols
});
}
onRemoveItem(i) {
this.setState({ items: _.reject(this.state.items, { i: i }) });
}
clearAllItem = ()=>{
this.setState({ items: [], charts: [] });
}
onRemoveChartItem(i){
this.setState({ charts: _.reject(this.state.charts, { i: i }) });
}
inputCanvasDimension = e =>{
const re = /^[0-9\b]+$/;
if (e.target.value === '' || re.test(e.target.value)) {
if(e.currentTarget.className === "inputWidth"){
this.setState({inputWidthVal: e.currentTarget.value});
}else if(e.currentTarget.className === "inputHeight"){
this.setState({inputHeightVal: e.currentTarget.value});
}
}
}
setCanvasDimension = () =>{
var canvas = document.getElementById("DetailLocationContainer");
if((this.state.inputWidthVal < 1000) || (this.state.inputHeightVal < 3000)){
alert("Width should not be less than 1000 and height should not be less than 3000");
}else {
canvas.style.width= this.state.inputWidthVal + "px";
canvas.style.height= this.state.inputHeightVal + "px";
}
}
saveToLS(key, value) {
var secondObject = Object.entries(value)[1];
if (global.localStorage) {
global.localStorage.setItem(
"rgl-8",
JSON.stringify({
[key]: value
})
);
}
}
onLayoutChange(layout, layouts) {
this.saveToLS("layouts", layouts);
}
onDrop = (layout, layoutItem, _event) => {
if(_event.dataTransfer.mozSourceNode.className === "textwidget"){
this.setState({
items: this.state.items.concat({
id: uuidV4(),
i: "n" + this.state.newCounter,
x: layoutItem.x,
y: layoutItem.y,
w: 1,
h: 1
}),
newCounter: this.state.newCounter + 1
});
}else if(_event.dataTransfer.mozSourceNode.className === "chart"){
this.setState({
// Add a new item. It must have a unique key!
charts: this.state.charts.concat({
id: uuidV4(),
i: "n" + this.state.chartCounter,
x: (this.state.charts.length * 2) % (this.state.cols || 12),
y: Infinity, // puts it at the bottom
w: 5,
h: 6
}),
// Increment the counter to ensure key is always unique.
chartCounter: this.state.chartCounter + 1
});
}
};
reset = () =>{
// window.location.reload(true);
this.setState({ layouts: {} });
}
render() {
return (
<div className="container" id="container">
<div className="btn_container">
<div>
<span>Width </span>
<input className="inputWidth" value={this.state.inputWidthVal} onChange={this.inputCanvasDimension}/>
<span> Height </span>
<input className="inputHeight" value={this.state.inputHeightVal} onChange={this.inputCanvasDimension}/>
<button onClick={this.setCanvasDimension}>Apply</button>
<button onClick={this.reset}><CachedIcon style={{fontSize: '14px'}}/></button>
<button onClick={openFullscreen}><FullscreenSharpIcon style={{fontSize: '14px'}}/></button>
</div>
</div>
<button id="createItemBtn" onClick={this.onAddItem}>Add Item</button>
<button id="createChartBtn" onClick={this.onChartItem}>Add Chart</button>
<button onClick={this.clearAllItem}>Clear All</button>
<div className="widgetcontainer">
<WidgetThumbnail
className="chart"
/>
<WidgetThumbnail
className="textwidget"
/>
</div>
<div className='DetailLocationContainer' id="DetailLocationContainer" >
<ResponsiveReactGridLayout
cols={{ lg: 1, md: 10, sm: 6, xs: 4, xxs: 2 }}
rowHeight={100}
onDrop={this.onDrop}
isDroppable={true}
isBounded={true}
layouts={this.state.layouts}
onLayoutChange={(layout, layouts) =>
this.onLayoutChange(layout, layouts)
}
onBreakpointChange={this.onBreakpointChange}
{...this.props}
>
{_.map(this.state.items, (el) => this.createElement(el))}
{_.map(this.state.charts, (el) => this.createChart(el))}
</ResponsiveReactGridLayout>
</div>
</div>
);
}
}
export default MinMaxLayout;
const rootElement = document.getElementById("root");
ReactDOM.render(<MinMaxLayout />, rootElement);
这是我的 getFrinLS
export function getFromLS(key) {
let md = {};
if (global.localStorage) {
try {
md = JSON.parse(global.localStorage.getItem("rgl-8")) || {};
} catch (e) {
/*Ignore*/
}
// console.log("return value ", md[key]);
return md[key];
}
}
似乎需要增量键才能应用更新后的布局。将键值从 el.id 更改为 i
createElement(el) {
const removeStyle = {
position: "absolute",
left: "11px",
top: 0,
cursor: "pointer"
};
const i = el.i;
return (
<div key={i} data-grid={el} >
<span
className="remove"
style={removeStyle}
onClick={this.onRemoveItem.bind(this, i)}
>
x
</span>
</div>
);
}