为每个按钮分配自己的单独状态计数

时间:2020-09-30 04:10:56

标签: javascript reactjs react-props

下面的代码显示了我当前的组件设计。这是一个计数器组件,它负责为相应的数组项目增加计数器,还负责将单击的项目添加到购物车。我试图找出是否有某种方法可以将items数组中的每个数组项分配给自己的状态计数值。当前,屏幕显示四个数组项,每个项旁边都有一个按钮,还有一个计数。单击任何特定项目的增量按钮时,所有按钮的状态计数都会更新并呈现,这不是我想要的。我试图以几种方式为每个按钮分配其自己的状态计数,但是还没有找出正确的方法。我想以某种方式将状态计数值绑定到每个按钮,以便每个按钮都有其各自的状态计数。如果有人可以提供一些提示或见解,我真的很感激,因为我不知道隔离每个按钮的状态计数的方法并使其唯一,以便在单击一个值的按钮时,仅更新该特定按钮(位于增量按钮旁边)的状态计数,而不会更新其他按钮。

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      cart: [],
    };
  }

  handleIncrement = (e) => {
    this.setState({
      count: this.state.count + 1,
      cart: [...this.state.cart, e.target.value],
    });
  };

  render() {
    const listItems = this.props.items.map((item) => (
      <li key={item.id}>
        {item.value}
        <button onClick={this.handleIncrement}>+</button>
        {this.state.count}
      </li>
    ));
    return (
      <div>
        {listItems}
      </div>
    );
  }
}

2 个答案:

答案 0 :(得分:1)

我在这里所做的是,我移除了constructor,更新了Counter组件道具,更新了有关如何更新Example组件中的购物车的事件,调整了Counter组件,对于Cart组件,我添加了componentDidMountshouldComponentUpdate确保仅在道具listArray更改时组件才会重新渲染。这是代码。

class Example extends React.Component {
    state = {
        cart: [],
        items: [
            { id: 1, value: "L1" },
            { id: 2, value: "L2" },
            { id: 3, value: "L3" },
            { id: 4, value: "L4" }
        ]
    }

    render() {
        const { cart } = this.state

        return (
            <div>
                <h1>List</h1>
                { items.map(
                    ({ id, ...rest }) => (
                        <Counter
                            key={ id }
                            { ...rest }
                            cart={ cart }
                            onAddToCard={ this.handleAddCart }
                        />
                    )
                ) }
            </div>
        )
    }

    handleAddCart = (item) => {
        this.setState(({ items }) => ([ ...items, item ]))
    }
}

class Counter extends React.Component {
    state = {
        count: 0
    }

    handleIncrement = () => {
        this.setState(({ count }) => ({ count: count++ }))
    }
    
    render() {
        const { count } = this.state
        const { cart, value } = this.props

        return (
            <div>
                { value }
                <span>
                    <button onClick={ this.handleIncrement }>+</button>
                    { count }
                </span>
                <Cart listArray={ cart } />
            </div>
        )
    }
}

class Cart extends React.Component {
    state = {
        cart: []
    }

    addTo = () => (
        <div>List: </div>
    )

    componentDidMount() {
        const { cart } = this.props

        this.setState({ cart })
    }

    shouldComponentUpdate({ listArray }) {
        return listArray.length !== this.state.cart.length
    }

    render() {
        return (
            <div>
                <ListFunctions addClick={ this.addTo } />
            </div>
        )
    }
}

const ListFunctions = ({ addClick }) => (
    <div>
        <button onClick={ addClick }>Add To List</button>
    </div>
)

答案 1 :(得分:0)

如果要添加到项目列表而不显示按钮,则可以添加一个自定义属性以标记它是自定义添加:

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [
        { id: 1, value: "L1" },
        { id: 2, value: "L2" },
        { id: 3, value: "L3" },
        { id: 4, value: "L4" },
      ]
    }
  }
  addToItems = items => {
    this.setState({
      items,
    });
  }
  render() {
    var cartArray = [];
    
    return (
      <div>
        <h1>List</h1>
        {this.state.items.map((item) =>
            <Counter
              key={item.id}
              value={item.value}
              id={item.id}
              custom={item.custom}
              cart={cartArray}
              addToItems={this.addToItems}
              items={this.state.items}
            />
        )}
      </div>
    );
  }
}

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }

  handleIncrement = () => {
    this.setState({
      count: this.state.count + 1,
    });
    this.props.cart.push(this.props.value);
  };
  addTo = () => {
    const { items } = this.props;
    let lastId = items.length;
    lastId++;
    this.props.addToItems([
    ...items,
    {
      id: lastId,
      value: `L${lastId}`,
      custom: true,
    }]);
  };
  render() {
    return (
      <div>
        {this.props.value}
        {
          !this.props.custom && 
          (
            <span>
              <button onClick={this.handleIncrement}>+                 </button>
              {this.state.count}
            </span>
          )
        }
        <Cart addTo={this.addTo} />
      </div>
    );
  }
}
class Cart extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
      return (
        <div>
          <ListFunctions
            addClick={this.props.addTo}
          />
        </div>
      );
    return null;
  }
}
const ListFunctions = ({ addClick}) => (
  <div>
    <button onClick={addClick}>Add To List</button>
  </div>
);

// Render it
ReactDOM.render(
  <Example />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>