为了账号安全,请及时绑定邮箱和手机立即绑定

尝试在 ReactJS 中拼接我的数组中的项目

尝试在 ReactJS 中拼接我的数组中的项目

繁华开满天机 2023-02-24 15:46:45
我正在尝试在 DoubleClick 事件上拼接我的列表(库存)中的一个项目,但有些东西无法正常工作。如果有人能如此友善并帮助我弄清楚我在这里做错了什么,那就太好了。对于信息:当我尝试切片一个项目时,它会被切片,但每次第一个项目和第二个项目都会丢失里面的所有内容:    function Inventory() {    const [datas, setData] = useState([      {        id: 1,         label: "Sword",        itemname: "grey_sword",        pieces: 1,        type: "weapon",      },      {        id: 2,         label: "Knife",        itemname: "grey_knife",        pieces: 1,        type: "weapon",      },    ]);    useEffect(() => {      const getItems = (data) => {        setData(data);      } // this section is for something else    }, [datas]);    const deleteItem = (index) => {      const test = ([], datas)      test.splice(index, 1)      setData([{test : datas}]);    }    const renderItem= (data, index) => {      return (        <Item          key={data.id}          id={data.id}          type={data.type}          label={data.label}          index={index}          name={data.itemname}          pieces={data.pieces}          deleteItem={deleteItem}        />      )    }    return (        <div className="inventory-holder">            <div className="inventory-main">              <div className="inventory-information">                <div className="inventory-title">                  Inventory                </div>                <div className="inventory-weight-info">                  0.20 kg / 1.00 kg                </div>                <div className="inventory-buttons">                  <button className="refresh-button" tabIndex="-1"><FontAwesomeIcon icon={faRedo} /></button>                  <button className="close-button" tabIndex="-1"><FontAwesomeIcon icon={faTimes} /></button>                </div>              </div>              <div className="items-holder">                <div>{datas.map((data, i) => renderItem(data, i))}</div>              </div>          </div>        </div>    )}export default Inventory;
查看完整描述

2 回答

?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

问题

Array::splice进行就地突变。

该方法通过移除或替换现有元素和/或就地splice()添加新元素来更改数组的内容。

这里的主要问题是状态突变。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator

const test = ([], datas)最终将状态引用保存datatest,然后由 进行变异test.splice(index, 1),然后奇怪的是被覆盖回不同的状态setData([{ test: datas }]);

解决方案

一种常见的模式是改用array::filter并在索引上进行过滤。filter返回一个新数组。

const deleteItem = (index) => { 
 setData(datas => datas.filter((_, i) => i !== index);
}


查看完整回答
反对 回复 2023-02-24
?
湖上湖

TA贡献2003条经验 获得超2个赞

您的项目太复杂了:


您可以直接使用道具,而无需通过您的div.


const Item = ({ index, id, type, label, name, pieces, deleteItem }) => {

  

    const useItem = () => {

      console.log(type + " " + index + " " + pieces )

      if(pieces <= 1){

        deleteItem(index);

      }

    }


    return(

        <div data-index={id} onDoubleClick={useItem} className="inventory-item">

            <img className="item-pic" src={chosedtype} ></img>

            <div className="item-label">{label}</div>

            <div className="item-number-pieces">{pieces}</div>

        </div>

    );

};


export default Item;

然后你的deleteItem功能不会做你想要的:


const deleteItem = (index) => {

  const test = ([], datas); //test = datas;

  test.splice(index, 1); // test = test without the item at the index

  setData([{test : datas}]);//data = [{test: datas}] so an array with an object with the property test = datas (the original array).

}

您应该将您的更改deleteItem为:


const deleteItem = (index) => {

    const newArray = datas.filter((item, i) => i !== index);

    setData(newArray);

}


查看完整回答
反对 回复 2023-02-24
  • 2 回答
  • 0 关注
  • 121 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信