Firebase возвращает нулевые ссылки, когда GET после DELETE - PullRequest
0 голосов
/ 11 января 2019

Я запускаю приложение реакции с Firebase в задней части. У меня есть конечная точка "/items".

Когда я вызываю запрос DELETE через Axios, база данных отображает правильные данные. Однако после запроса DELETE, когда я вызываю запрос GET для получения обновленных «элементов», я получаю нулевую ссылку, где находился удаленный элемент, что приводит к ошибке нулевой ссылки.

EXAMPLE
-Original [item1, item2, item3]
*Delete item2

-Get
   - [item1, null, item3]

Однако на Firebase это отражается правильно ..

class VendingMachine extends Component {
    state = {
        balance: "",
        items: [],
    }

getItems = () => {
    axios.get('items.json')
        .then(response => {
            if (response.data) {
                this.setState({ items: Object.values(response.data) });
            }
        })

}


deleteItemHandler = (id) => {
    axios.delete('/items/' + id + '.json')
        .then((response) => {
            this.getItems();
        });

}

Запрос на поставку находится в другом компоненте.

class NewItem extends Component {

    errorElement = React.createRef();

    state = {
        newItem: {
            name: "",
            position: null,
            price: "",
            image: ""
        },
        showError: false
    };

    addItemHandler = () => {
        if (this.props.items.length === 9) {
            this.setState({ showError: true });
            return;
        }
        const newItem = {
            id: this.props.items.length,
            name: this.state.newItem.name,
            price: this.state.newItem.price,
            image: this.state.newItem.image,
            position: this.props.items.length

        }
        console.log(newItem);
        axios.put('/items/' + newItem.id + '.json', newItem)
            .then(response => {
                this.props.updateItems()
            })
            .catch(error => console.log(error));
    }

1 Ответ

0 голосов
/ 11 января 2019

Это ожидаемое поведение при хранении массивов в Firebase.

Когда вы храните:

["item1", "item2", "item3"]

Сервер базы данных Firebase хранит его как:

{
  "0": "item1",
  "1": "item2",
  "2": "item3"
}

И это означает, что при удалении item2 вы получите:

{
  "0": "item1",
  null,
  "2": "item3"
}

Который клиент Firebase затем переводит обратно:

["item1", null, "item3"]

У вас есть два варианта:

  1. Всегда обновлять весь массив
  2. Использовать набор вместо массива

Всегда обновлять весь массив

Если вы хотите сохранить элементы в виде массива, вам придется перенумеровать индекс для всех элементов после тех, которые вы удалили. Это означает, что любое обновление массива означает, что вам нужно читать и записывать весь массив.


Использовать набор вместо массива

Но на самом деле вы не можете хранить массив. Многие разработчики используют массивы для хранения структур данных, подобных множеству, то есть неупорядоченных коллекций уникальных элементов. Например: ["item3", "item2", "item1"] имеет то же значение в ["item1", "item2", "item3"]? И действительно ли ["item1", "item1", "item2", "item3"] незаконно в вашем приложении? Если это так, вы смотрите на структуру данных, подобную множеству, которая в Firebase лучше сопоставлена ​​с:

{
  "item1": true,
  "item2": true,
  "item3": true
}

Значение true не имеет смысла и необходимо только потому, что Firebase не будет хранить ключ без значения. Но кроме этого, это лучшая структура для хранения подобной коллекции. И если вы удалите item2 из этого, Firebase просто вернет объект без этого ключа:

{
  "item1": true,
  "item2": true,
  "item3": true
}

Подробнее об этом также см .:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...