typescript 创建一个状态作为一个布尔数组是给我一个空数组,为什么?

wsewodh2  于 2023-05-19  发布在  TypeScript
关注(0)|答案(1)|浏览(92)

我试图创建一个组件,将显示从我的数据库中的产品与复选框中的每一个。然后,我应该能够删除所有检查的项目从数据库中按下一个按钮,在标题组件。
这是正在进行的工作:

import React, { useState, useEffect } from "react";
import { Container, ItemDescription, ProductContainer } from "./style";
const API = "http://localhost:4000/select";

interface DATA {
  sku: string,
  name: string, 
  price: string,
  type: string,
  size: number,
  weight: number,
  height: number,
  width: number,
  length: number,
}

interface IProps {
  del: boolean
}

const ProductDisplay = ({del}:IProps) => {
  const [productList, setProductList] = useState<Array<DATA>>([]);
  var checked = new Array(productList.length).fill(false); // this gives me what I want
  const [checkedItems, setCheckedItems] = useState(checked); // here it gives me an empty undefined array
  const [deleteList, setDeleteList] = useState<Array<DATA>>([]);
  
  useEffect(() => {
    const fetchData = async (data: any) => {
      try {
        const response = await fetch(data);
        const results = await response.json();
        setProductList(results);
      } catch (e) {
        console.log(e);
      }
    };
    fetchData(API);
  }, []);

  const handleOnChange = (position:number) => {
    const updatedCheckedItems = checkedItems.map((item, index) =>
      index === position ? !item : item
    );

    setCheckedItems(updatedCheckedItems);

      const skuList = updatedCheckedItems.reduce(
      (currentState, index) => {
        if (currentState === true) {
          return productList[index].sku;
        }
        return null;
      }
    );

    setDeleteList(skuList);

    console.log(checkedItems);
   };

  return (
    <div>
        {productList.length === 0 && <h4>Fetching Checkboxes ...</h4>}
        {productList.length > 0 &&
            <Container>
                {productList.map((item: any, index) => (
                    <ProductContainer>              
                        <input type="checkbox"
                            value={item.sku}
                            id={`custom-checkbox-${index}`}
                            checked={checkedItems[index]}
                            onChange={() => handleOnChange(index)}
                        />
                        <ItemDescription>
                            <span className="sku" >{item.sku}</span>
                            <span className="name" >{item.name}</span>
                            <span className="price" >{item.price} $</span>
                            {item.size && <span className="size" >Size: {item.size}MB</span>}
                            {item.weight && <span className="weight" >Weight: {item.weight}KG</span>}
                            {item.height && <span className="dimention" >Dimention: {item.height} x {item.width} x {item.length}</span>}
                        </ItemDescription>
                    </ProductContainer>
                ))}
            </Container>  
        }
     );
};

export default ProductDisplay;

产品显示工作正常,checked变量显示了我想要的带有11个假布尔值的数组,但是checkeItems的状态给了我一个空数组。正因为如此,我还没有能够测试其余的代码是否允许我从选中的项目中生成一个SKU列表以进行删除。
我尝试创建新数组作为起始状态,结果相同:

const [checkedItems, setCheckedItems] = useState(
new Array(productList.length).fill(false)
);

我是一个新手,感谢任何帮助,谢谢!

4nkexdtk

4nkexdtk1#

在两个render中向useState(checked)传递两个不同的参数,它只使用第一个参数(空数组)作为initValue。
你应该使用useEffect。就像:

function App() => {
  const [productList, setProductList] = useState<Array<DATA>>([]);
  const [checkedItems, setCheckedItems] = useState<Array<Boolean>>([]);

  useEffect(() => {
    const fetchData = async (data: any) => {
      try {
        const response = await fetch(data);
        const results = await response.json();
        setProductList(results);
        //
        const checked = new Array(results.length).fill(false);
        setCheckedItems(checked)
      } catch (e) {
        console.log(e);
      }
    };
    fetchData(API);
  }, []);
  
  // ......
}

在react18之后,useEffect中的setProductListsetCheckedItems只会导致一次重新渲染。参见Automatic batching for fewer renders in React 18

相关问题