繁体   English   中英

如何在 useState 挂钩中创建一个字符串数组并在 TypeScript 中更新同一个数组?

[英]How to create a string array in the useState hook and update that same array in TypeScript?

我有一个 React 项目,我正在尝试创建一个多 select function,您可以在其中 select 并一次取消选择多个头像。

到目前为止我有这个:

export interface IStoreRecommendationProps {
  title: string;
  description: string;
  discountNumber: number;
  discountItem: string;
  arr: string[];
  onClickAvatar: () => void; // pass a specific parameter for avatar
}

export const StoreRecommendation: React.FC<IStoreRecommendationProps> = ({
  title,
  description,
  discountNumber,
  discountItem,
  arr,

  onClickAvatar,
  ...props
}) => {
  const [visible, setVisible] = useState({
    arr[],
  });
  const showIcon = (id) => {
    arr.push(id);
    console.log(arr);
    setVisible(id);
    onClickAvatar();
  };

  const displayContacts = () =>
    CUSTOMERS.map((person) => (
      <AvatarContainer>
        <Avatar
          picture={{uri: person.profile_picture}}
          onPress={() => showIcon(person.customer_id)}
        />
        <TextAvatar>{person.name}</TextAvatar>
        {visible.includes(person.customer_id) && <CheckIcon />}
      </AvatarContainer>
    ));

在 showIcon() 中,我试图在 state 中保存一个 ID 数组并相应地更新它们(如果单击则推送,如果再次单击则删除)然后通过执行 visible.includes(person.customer_id) 检查 displayContacts() 中的数组)

const [visible, setVisible] = useState({
    arr[],
  });
  const showIcon = (id) => {
    arr.push(id);
    console.log(arr);
    setVisible(id);
    onClickAvatar();
  };
const displayContacts = () =>
    CUSTOMERS.map((person) => (
      <AvatarContainer>
        <Avatar
          picture={{uri: person.profile_picture}}
          onPress={() => showIcon(person.customer_id)}
        />
        <TextAvatar>{person.name}</TextAvatar>
        {visible.includes(person.customer_id) && <CheckIcon />}
      </AvatarContainer>
    ));

我从一个单独的文件中抓取客户,它看起来像这样:

export const CUSTOMERS = [
  {
    customer_id: '1',
    name: "John Doe",
    profile_picture: "https://img.freepik.com/free-photo/portrait-white-man-isolated_53876-40306.jpg?size=626&ext=jpg",
    approval_status: false,
    payment_method: Enums.OrderPaymentMethod.IN_PERSON
  },
  {
    customer_id: '2',
    name: "Evan Green",
    profile_picture: "https://media.istockphoto.com/photos/portrait-concept-picture-id1016761216?k=6&m=1016761216&s=612x612&w=0&h=j-DyZTSqmnhoHKsJdGmiMPnungpHiq9UTrvx4UylMQI=",
    approval_status: false,
    payment_method: Enums.OrderPaymentMethod.IN_PERSON
  },
  {
    customer_id: '3',
    name: "Grace Lewis",
    profile_picture: "https://img.freepik.com/free-photo/friendly-brunette-looking-camera_23-2147774849.jpg?size=626&ext=jpg",
    approval_status: false,
    payment_method: Enums.OrderPaymentMethod.IN_PERSON
  }, ...]

现在,当我尝试执行 visible.includes() 时,出现错误,它告诉我我的数组类型为 never。 我是否对 useState() 挂钩进行了数组初始化错误,我是否在正确的轨道上做我想做的事情?

您的意思是将visible初始化为数组,然后通过setVisible与该数组交互,而不是直接操作方法。
尝试这样的事情:

const [visible, setVisible] = useState([]);

  const showIcon = (id) => {
    setVisible([...visible, id])
    console.log(visible);
    onClickAvatar();
  };

假设您的可见初始状态是一个像[34, 63, 12]这样的 id 数组并且您调用showIcon(20) ,它应该更新visible并注销到[34, 63, 12, 20]

尝试以下,解决问题(希望:)):

  1. 代替

const [visible, setVisible] = useState({ arr[],});

const [visible, setVisible] = useState<string[]>([]);

正确的初始化和类型定义

  1. 代替

    const showIcon = (id) => { arr.push(id); console.log(arr); setVisible(id); onClickAvatar(); };

     const showIcon = (id) => {
         setVisible(prevState => {
         // check if it is already added
         if(prevState.includes(id)) { 
           // clone the prevState arr to prevent side effects  
            const clone = [...prevState];
          // Remove the existing id 
            clone.splice(prevState.indexOf(id), 1)
            return clone;
         } else {
            return [...prevState, id]
         }});
         onClickAvatar();
     };

 

注意: arr在这里不相关,因为它没有在其他地方使用并且是多余的,因此应该将其删除

我被阻止了,我尝试了一切……解决方案?

德鲁里斯的评论

我建议使用功能更新,setVisible(visible => [...visible, id]) 所以 state 从之前的 state 更新而不是 state 在回调 scope 中关闭,并且控制台日志将只记录当前的 state,而不是它的内容将更新为下一个渲染。

仅仅使用这个给了我不好的结果:

setVisible([...visible, id])

但完美搭配:

setVisible(visible => [...visible, id])

非常感谢!

暂无
暂无

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

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