【问题标题】:Deleting/Updating nested object using React Hooks使用 React Hooks 删除/更新嵌套对象
【发布时间】:2020-04-29 18:24:21
【问题描述】:

我对 react-native 编程语言比较陌生。我一直在尝试制作我的第一个独立应用程序,当然是 To Do List 应用程序。 我必须在各自的类别下做项目。这些待办事项的来源是一个预定义的对象,如下所示。

const [listData, setListData] = useState([
{
  id: 1,
  title: "Work",
  data: [
    {
      text: 'MSD',
      key: 1
    },
    {
      text: 'Cosmo',
      key: 2
    },
    {
      text: 'Jackson',
      key: 3
    },
  ]
},
{
  id: 2,
  title: "Home",
  data: [
    {
      text: 'Gym',
      key: 4
    },
    {
      text: 'Dinner',
      key: 5
    },
    {
      text: 'React',
      key: 6
    },
  ]
},
  ]);

此数据在主函数 App() 中定义。使用以下代码,数据在屏幕上完美呈现。 Home Screen Image

return(
<View style={styles.container}>
  <Header />
  <SectionList
    sections={listData}
    keyExtractor={(item, index) => item + index}
    renderSectionHeader={({ 
      section: { title } }) => (
        <Text style={styles.header}>{title}</Text>
    )}
    renderItem={({ item }) => <Item data={item.text} dataID={item.key} onDeleteHandler={onDeleteHandler}/>}
  />
</View>
  )

Item 组件代码是 -

const Item = ({ data, dataID, onDeleteHandler }) => {

const [checked, setChecked] = React.useState(false);

return(
<View style={styles.itemGroup}>
  <TouchableOpacity style={styles.item} onPress={() => {
    if (checked == true){ 
      setChecked(false)
    }
    else{
      setChecked(true)
    }
  }}>
    <View>
      <Text style={checked === true ? styles.toDoTextStrikeThrough : styles.toDoText}>{data}</Text>
    </View>
  </TouchableOpacity>
  <TouchableOpacity onPress={() => onDeleteHandler(dataID)}>
    <View style={styles.checkBoxAndDeleteStyle}>
      <Entypo name="cross" color='#004d4d' size={18}/>
    </View>
  </TouchableOpacity>
</View>
)
};

export default Item;

我被卡住的地方是调用以下函数的删除按钮。

  const onDeleteHandler = (key) => {

const parentArray = [...listData]

  for (let i = 0; i < parentArray.length; i++)
  {
    let paDataItems = {...parentArray[i]}.data
    const dataArray = [...paDataItems]
    for (let k = 0; k < dataArray.length; k++){
      if (dataArray[k].key === key){
        dataArray.splice(k,1)
        break
      }
    }
    console.log(dataArray)
  }
  }

dataArray 显示所有正确的对象。我无法弄清楚如何将其更新回主数据集。 我已经尝试了以下两种方法,但都导致了奇怪的行为。

    setListData((paDataItems) => [...paDataItems,{data:dataArray}])

    setListData([{...parentArray[i]}, {data:dataArray}])

我应该如何编写这个函数才能删除选定的项目? 我想一旦我解决了上述问题,我应该能够弄清楚如何更新数据集。

任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: reactjs react-native react-redux react-hooks


    【解决方案1】:

    您可以映射组/类别并过滤数据数组:

    const onDeleteHandler = key => {
      const newData = listData.map(category => ({
          ...category,
          data: category.data.filter(item => item.key !== key)
        })
      );
      setListData(newData);
    };
    

    使用功能状态更新可能更正确,因为在单个渲染周期内多个状态更新排队的情况下,下一个状态取决于前一个状态正确删除了任务项:

    const onDeleteHandler = key => {
      setListData(listData => listData.map(category => ({
          ...category,
          data: category.data.filter(item => item.key !== key)
        })
      ));
    };
    

    let data = [{
        id: 1,
        title: "Work",
        data: [{
            text: 'MSD',
            key: 1
          },
          {
            text: 'Cosmo',
            key: 2
          },
          {
            text: 'Jackson',
            key: 3
          },
        ]
      },
      {
        id: 2,
        title: "Home",
        data: [{
            text: 'Gym',
            key: 4
          },
          {
            text: 'Dinner',
            key: 5
          },
          {
            text: 'React',
            key: 6
          },
        ]
      },
    ];
    
    const onDeleteHandler = key => {
      const newData = data.map(category => ({
          ...category,
          data: category.data.filter(item => item.key !== key)
        })
      );
      return newData;
    };
    
    console.log(onDeleteHandler(3))

    【讨论】:

    • 太棒了!谢谢你的指导。我现在明白了。
    • @HrishikeshDeshkar 不客气。如果问题得到充分解决,请接受答案。
    【解决方案2】:

    您可以像这样简化onDeleteHandler 函数:

    const newData = listData.map(group => {
        return { 
            ...group,
            data: group.data.filter(task => task.key !== key)
        }
    })
    setListData(newData);
    

    【讨论】:

    • 感谢您的帮助。只是 setListData(newData) 在您的 sn-p 中无法访问。我不得不将它从 newData 的代码中移出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-21
    • 1970-01-01
    • 2020-01-07
    相关资源
    最近更新 更多