简体   繁体   English

带有反应钩子的多个计数器

[英]Multiple counters with react hooks

I'm trying to use a custom react hook to create a counter for each item in a list.我正在尝试使用自定义反应钩子为列表中的每个项目创建一个计数器。 the problem is when I increase or decrease a counter, the value of other counters change simultaneously.问题是当我增加或减少一个计数器时,其他计数器的值会同时改变。 basically all of the counters show the same value.基本上所有的计数器都显示相同的值。 here is my custom hook:这是我的自定义钩子:

import { useState } from "react";

export const useQuantity = (defaultQuantity) => {
const [value, setValue] = useState(defaultQuantity || 1);

const onChange = (e) => {
 if (!+e.target.value >= 1) {
    setValue(1);
    return;
 }
 setValue(+e.target.value);
};

return {
  value,
  setValue,
  onChange,
 };
};

how can I change the value of a counter while it doesn't effect the other counters?如何在不影响其他计数器的情况下更改计数器的值?

This is the component that I map through the items and for each one of them I render the QuantityInput component.这是我通过项目 map 的组件,我为每个项目呈现 QuantityInput 组件。

import { useQuantity } from "../Hook/useQuantity";
import { QuantityInput } from "./QuantityInput";

export const Order = () => {
    const quantity = useQuantity();

    return (
       orders.map((order) => (
          <QuantityInput quantity={quantity} />
       )
    )
  }

and this is QuantityInput component:这是 QuantityInput 组件:

export const QuantityInput = ({ quantity }) => {

  const decrement = () => {
     quantity.setValue(quantity.value - 1);
  };

  const increment = () => {
    quantity.setValue(quantity.value + 1);
  };

  return (
    <Button
      onClick={decrement}
      disabled={quantity.value === 1}
    >
      -
    </Button>
    <Input {...quantity} />
    <Button onClick={increment}> + </Button>
    );
   };

Instead of useQuantity in your parent component, you should use it in QuantityInput component so each of them hold their state.您应该在QuantityInput组件中使用它,而不是在父组件中使用它,以便它们每个人都持有自己的useQuantity

export const QuantityInput = () => {
  const quantity = useQuantity(); // Use quantity here, do not need to pass from props

  const decrement = () => {
     quantity.setValue(quantity.value - 1);
  };

  const increment = () => {
    quantity.setValue(quantity.value + 1);
  };

  return (
    <Button
      onClick={decrement}
      disabled={quantity.value === 1}
    >
      -
    </Button>
    <Input {...quantity} />
    <Button onClick={increment}> + </Button>
  );
};

The hook that you implemented holds one state value and will only suffice for it.您实现的钩子包含一个 state 值,仅够用。

The solution here is to implement a component that uses this hook.这里的解决方案是实现一个使用这个钩子的组件。 Once you have the component you can render as many instances of it as you want拥有组件后,您可以根据需要渲染尽可能多的实例

Also you could simply implement a component instead of custom hook你也可以简单地实现一个组件而不是自定义钩子

import { useState } from "react";

export const QuantityInput = (props) => {
    const [value, setValue] = useState(props.defaultQuantity || 1);

    const onChange = (e) => {
       if (!+e.target.value >= 1) {
          setValue(1);
          return;
       }
       setValue(+e.target.value);
    };

   return (
      <div>
          <div>{value}</div>
          <input value={value} onChange={onChange} />
      </div>

    )
};


const Parent = ({arr}) => {
   return arr.map(item => <QuantityInput defaultQuantity={item.defaultQuantity} />)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM