Удаление / Обновление вложенного объекта с помощью React Hooks - PullRequest
0 голосов
/ 29 апреля 2020

Я относительно новичок в реактивном языке программирования. Я пытался сделать свое первое отдельное приложение, которое, конечно же, является списком дел. Я должен делать предметы под свои соответствующие категории. Источником этих элементов для выполнения является предопределенный объект, как показано ниже.

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 (). Данные отлично отображаются на экране с кодом ниже. Изображение главного экрана

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>
  )

Код компонента элемента - -

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}])

Как мне написать эту функцию, чтобы я мог удалить выбранный элемент? Я предполагаю, что смогу выяснить, как обновить набор данных, как только у меня будет решение вышеуказанной проблемы.

Любая помощь будет принята с благодарностью. Спасибо.

Ответы [ 2 ]

0 голосов
/ 29 апреля 2020

Вы можете отобразить группы / категории и отфильтровать массив данных:

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))
0 голосов
/ 29 апреля 2020

Вы можете упростить вашу onDeleteHandler функцию следующим образом:

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