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}/>
          &nbsp;&nbsp;
          <span> Height </span>
          <input className="inputHeight" value={this.state.inputHeightVal} onChange={this.inputCanvasDimension}/>
          &nbsp;&nbsp;
          <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"
          /> 
          &nbsp;&nbsp;
          <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>
    );
  }