React

#reactjs #firebase

#reactjs #firebase

Вопрос:

Привет, я надеюсь, что у вас пока хороший день, у меня есть проблема, которую я хотел бы попросить о помощи, если вы можете помочь, пожалуйста, не стесняйтесь ответить на вопрос ниже.

Итак, у меня есть коллекция Firebase с именем «учетные записи», и я хочу установить для этого документа массив внутри моего документа с именем «корзина». Это работает нормально, но есть проблема, и это useState, в котором у меня есть мой массив (я передаю useState с помощью map в корзину). Сначала передается пустой массив, который является значением useState по умолчанию, но причина, по которой я запутался, заключается в том, что значение, которое я передаю в useState, обновляется нормально и имеет значение, но когда я console.log или обновляю свой массив с помощью useState, он не содержитдобавляется массив, только при втором нажатии на него.

Это код, который его запускает.

 const [addBasket, setBasket] = useState([]);    

const addToBasketCollection = (name) => {
    setBasket([...addBasket, name.toLowerCase()])
    const user = auth.currentUser;
    console.log('Name: '   name, 'nArray: '   [...addBasket, name.toLowerCase()], 'nWhy does this not update: ', addBasket)
    db.collection('accounts').doc(user.uid).set(({
        basket: addBasket.map(doc => doc),
    }), { merge: true })
}


<button className="item-info__button" onClick={() => { addToBasketCollection(product.info.name) }}>Add</button>
  

Примечание:
Console.log() выше возвращает это при первом нажатии кнопки:

 Name: Mori 
Array: more 
Why does this not update:  []
  

При втором нажатии кнопки он возвращает это:

 Name: Mori 
Array: more 
Why does this not update:  ["mori] // "mori" is the item's name that I added.
  

Ответ №1:

addBasket является локальной константой. Это никогда не изменится, и это не то, что setBasket пытается сделать. Установка состояния — это инструкция для реагирования на повторный запуск компонента. При этом новом рендеринге будет создан новый локальный const с новым значением. Код в новом рендеринге сможет увидеть новое значение; код в старом рендеринге не может.

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

 const [addBasket, setBasket] = useState([]);    

console.log('rendering with: ', addBasket);

const addToBasketCollection = (name) => {
    const newBasket = [...addBasket, name.toLowerCase()];
    setBasket(newBasket)
    const user = auth.currentUser;
    db.collection('accounts').doc(user.uid).set(({
        basket: newBasket.map(doc => doc),
    }), { merge: true })
}