根据条件反应更新状态启动计数器

时间:2018-01-16 14:29:52

标签: javascript reactjs

我有以下组件:

import React from "react";
import ReactDOM from "react-dom";
import { WidthProvider, Responsive } from "react-grid-layout";
import _ from "lodash";
const ResponsiveReactGridLayout = WidthProvider(Responsive);
const originalLayout = getFromLS("layout") || [];

/**
 * This layout demonstrates how to use a grid with a dynamic number of elements.
 */
class AddRemoveLayout extends React.PureComponent {
  static defaultProps = {
    className: "layout",
    cols: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 },
    rowHeight: 100,
    onLayoutChange: function(){}
  };

  constructor(props) {
    super(props);

    this.state = {
      items: originalLayout.map((i, key, list) => {
        return {
          i: i.i.toString(),
          x: i.x,
          y: i.y,
          w: i.w,
          h: i.h,
          add: i.i === (list.length - 1).toString()
        };
      }),
      newCounter: 0,
      layout: JSON.parse(JSON.stringify(originalLayout))
    };

    this.onAddItem = this.onAddItem.bind(this);
    this.onBreakpointChange = this.onBreakpointChange.bind(this);
    this.onLayoutChange = this.onLayoutChange.bind(this);

    this.widgetID = [];
  }


  onAddItem(layout) {
    this.widgetID.length === 0 ? console.log('empty') : console.log("n" + (this.widgetID.slice(-1)[0] + this.state.newCounter))
        // this.setState({
        // // Add a new item. It must have a unique key!
        //   items: this.state.items.concat({
        //     i: "n" + this.state.newCounter,
        //     x: (this.state.items.length * 2) % (this.state.cols || 12),
        //     y: Infinity, // puts it at the bottom
        //     w: 2,
        //     h: 2
        //   }),
        //   // Increment the counter to ensure key is always unique.
        //   newCounter: this.state.newCounter + 1
        // })


        // this.setState({
        // // Add a new item. It must have a unique key!
        //   items: this.state.items.concat({
        //     i: "n" + (this.widgetID.slice(-1)[0] + this.state.newCounter),
        //     x: (this.state.items.length * 2) % (this.state.cols || 12),
        //     y: Infinity, // puts it at the bottom
        //     w: 2,
        //     h: 2
        //   }),
        //   // Increment the counter to ensure key is always unique.
        //   newCounter: this.state.newCounter + 1
        // }}
    this.setState({
      newCounter: this.state.newCounter + 1
    })

    this.widgetID.push(this.state.newCounter);

    saveToLS("widget-id", this.widgetID, 'widget-id');
  }

  render() {  
    return (
      <div>
        <button onClick={this.onAddItem}>Add Item</button>
        <ResponsiveReactGridLayout
          onLayoutChange={(layout) =>
            this.onLayoutChange(layout)
          }
        >
          {_.map(this.state.items, el => this.createElement(el))}
        </ResponsiveReactGridLayout>
      </div>
    );
  }
}

function saveToLS(key, value, item) {
  if (global.localStorage) {
    global.localStorage.setItem(
      item,
      JSON.stringify({
        [key]: value
      })
    );
  }
}

function getFromLS(key) {
  let ls = {};
  if (global.localStorage) {
    try {
      ls = JSON.parse(global.localStorage.getItem("layout")) || {};
    } catch (e) {
      /*Ignore*/
    }
  }
  return ls[key];
}

export default AddRemoveLayout;

在“onAddItem”函数中我有:

this.widgetID.length === 0 ? console.log('empty') : console.log("n" + (this.widgetID.slice(-1)[0] + this.state.newCounter))

如果这是真的

this.widgetID.length === 0

我希望这种情况发生:

    // this.setState({
    // // Add a new item. It must have a unique key!
    //   items: this.state.items.concat({
    //     i: "n" + this.state.newCounter,
    //     x: (this.state.items.length * 2) % (this.state.cols || 12),
    //     y: Infinity, // puts it at the bottom
    //     w: 2,
    //     h: 2
    //   }),
    //   // Increment the counter to ensure key is always unique.
    //   newCounter: this.state.newCounter + 1
    // })

否则我希望计数器从

中的最后一个值开始
this.widgetID

如果“this.widgetID”的最后一个值为6,则计数应从6开始,这样我们得到7,8,9。我试过这个但没有运气:

    // this.setState({
    // // Add a new item. It must have a unique key!
    //   items: this.state.items.concat({
    //     i: "n" + (this.widgetID.slice(-1)[0] + this.state.newCounter),
    //     x: (this.state.items.length * 2) % (this.state.cols || 12),
    //     y: Infinity, // puts it at the bottom
    //     w: 2,
    //     h: 2
    //   }),
    //   // Increment the counter to ensure key is always unique.
    //   newCounter: this.state.newCounter + 1
    // }}

我正在向页面添加小部件,每个小部件必须具有唯一的ID。我保存了本地存储的每一个添加项,以便我可以检索最后一个id并从那里开始计数,否则我收到错误

1 个答案:

答案 0 :(得分:1)

当你setState考虑​​到以前的状态时,正确的方法是传递updater函数(而不是你正在做的新状态对象):

  

setState(updater [,callback])

更新程序功能是:

  

(prevState,道具)=&gt; stateChange

考虑到这一点,我会尝试以下方法:

this.setState((prevState, props) => ({
  // Add a new item. It must have a unique key!
  items: prevState.items.concat({
    i: "n" + prevState.newCounter,
    x: (prevState.items.length * 2) % (prevState.cols || 12),
    y: Infinity, // puts it at the bottom
    w: 2,
    h: 2
  }),
  // Increment the counter to ensure key is always unique.
  newCounter: prevState.newCounter + 1
}))

这样,由于批量状态更新,您的组件状态将永远不会同步。