Ваша проблема в том, что вы меняете состояние случайно. Похоже, в этом случае React решает не перерисовывать ваш компонент, поэтому reorderActiveCardsDown
по-прежнему содержит старые данные.
Также вы храните экземпляры ваших функций внутри компонентов, которые находятся в состоянии, поэтому функции выиграли нет нового состояния внутри них. (только компоненты в return
rerender)
Чтобы исправить это, вы должны использовать функцию обновления , поэтому вы всегда используете последнее состояние.
const reorderActiveCardsDown = () => {
setActiveCards((oldArray) => {
let newArray = Array.from(oldArray) //create a fresh array from the current one
console.log(oldArray)
const swapPositions = (array, a ,b) => {
[array[a], array[b]] = [array[b], array[a]]
}
swapPositions(newArray, index, index+1);
return newArray
});
}
Если вы устанавливаете новое состояние на основе предыдущего значения, вы всегда должны использовать средство обновления, поэтому измените все остальные функции соответствующим образом.
Вы никогда не должны хранить экземпляры компонентов (например, <MyComponent myProp={value} />
) в состоянии, потому что тогда реквизиты вообще не обновятся, и вы столкнетесь со странными побочными эффектами, подобными тем, которые вы могли испытать здесь. Чтобы избежать этого, я заменил activeCards
на activeCardData
, в котором хранятся только данные, необходимые для функции mapQuoteCard
, которая создает окончательный экземпляр компонента, который должен быть визуализирован.
import React, { Component, useState, useEffect } from "react"
import NewCardModal from "./SetupCards/NewCardModal"
import BaseCostCard from "./SetupCards/BaseCostCard"
import DatePickerCard from "./SetupCards/DatePickerCard"
import TimedRateCard from "./SetupCards/TimedRateCard"
import TextCard from "./SetupCards/TextCard"
import SelectCard from "./SetupCards/SelectCard"
import CheckboxCard from "./SetupCards/CheckboxCard"
import NumberCard from "./SetupCards/NumberCard"
import SliderCard from "./SetupCards/SliderCard"
import { Container } from "reactstrap"
let updateCumulativeList = true
const AqgSetup2 = (props) => {
const [_id, setId] = useState("5e888116ea81f0eae86517de")
const [activeCardData, setActiveCardData] = useState([])
const [cumulativeList, setCumulativeList] = useState([])
const fetchIDS = async () => {
try {
const response = await fetch(
`/api/autoquotegenerators/5e888116ea81f0eae86517de`
)
const responseData = await response.json()
setCumulativeList(responseData.quoteGenerator)
// console.log(responseData.quoteGenerator)
} catch (error) {
console.error(error)
}
}
useEffect(() => {
fetchIDS()
console.log("fetched")
}, [])
useEffect(() => {
if (updateCumulativeList) {
setTimeout(() => {
convertIdToCard()
updateCumulativeList = false
}, 300)
} else {
console.log(updateCumulativeList)
}
cumulativeListPut()
}, [cumulativeList])
useEffect(() => {
console.log("active cards updated")
}, [activeCardData])
const convertIdToCard = () => {
const quoteCards = []
quoteCards.push(
cumulativeList.map((id) => {
return id
})
)
const selfMap = async (quoteCards) => {
if (quoteCards.length > 0) {
try {
let card = quoteCards.shift()
const response = await fetch(
`/api/autoquotegenerators/${card}`
)
const responseData = await response.json()
createQuoteCards(responseData)
selfMap(quoteCards)
} catch (error) {
console.error(error)
}
}
}
selfMap(quoteCards[0])
}
const createQuoteCards = (quoteCard) => {
setActiveCardData((previousTypes) => [...previousTypes, quoteCard])
}
const mapQuoteCard = (quoteCard) => {
switch (quoteCard.quoteGenerator[0].cardType) {
case "base":
return (
<BaseCostCard
id={quoteCard._id}
cardTitle={quoteCard.quoteGenerator[0].cardTitle}
charge={quoteCard.quoteGenerator[0].charge}
deleteCard={deleteCard}
moveCardDown={moveCardDown}
/>
)
case "date":
return (
<DatePickerCard
id={quoteCard._id}
cardTitle={quoteCard.quoteGenerator[0].cardTitle}
charge={quoteCard.quoteGenerator[0].charge}
advanced={quoteCard.quoteGenerator[0].advanced}
sunday={quoteCard.quoteGenerator[0].sunday}
monday={quoteCard.quoteGenerator[0].monday}
tuesday={quoteCard.quoteGenerator[0].tuesday}
wednesday={quoteCard.quoteGenerator[0].wednesday}
thursday={quoteCard.quoteGenerator[0].thursday}
friday={quoteCard.quoteGenerator[0].friday}
saturday={quoteCard.quoteGenerator[0].saturday}
deleteCard={deleteCard}
moveCardDown={moveCardDown}
/>
)
case "timed":
return (
<TimedRateCard
id={quoteCard._id}
cardTitle={quoteCard.quoteGenerator[0].cardTitle}
charge={quoteCard.quoteGenerator[0].charge}
deleteCard={deleteCard}
moveCardDown={moveCardDown}
/>
)
case "text":
return (
<TextCard
id={quoteCard._id}
cardTitle={quoteCard.quoteGenerator[0].cardTitle}
charge={quoteCard.quoteGenerator[0].charge}
deleteCard={deleteCard}
moveCardDown={moveCardDown}
/>
)
case "select":
return (
<SelectCard
id={quoteCard._id}
cardTitle={quoteCard.quoteGenerator[0].cardTitle}
charge={quoteCard.quoteGenerator[0].charge}
selectOptions={
quoteCard.quoteGenerator[0].selectOptions
}
deleteCard={deleteCard}
moveCardDown={moveCardDown}
/>
)
case "check":
return (
<CheckboxCard
id={quoteCard._id}
cardTitle={quoteCard.quoteGenerator[0].cardTitle}
charge={quoteCard.quoteGenerator[0].charge}
deleteCard={deleteCard}
moveCardDown={moveCardDown}
/>
)
case "number":
return (
<NumberCard
id={quoteCard._id}
cardTitle={quoteCard.quoteGenerator[0].cardTitle}
charge={quoteCard.quoteGenerator[0].charge}
deleteCard={deleteCard}
moveCardDown={moveCardDown}
/>
)
case "slider":
return (
<SliderCard
id={quoteCard._id}
cardTitle={quoteCard.quoteGenerator[0].cardTitle}
charge={quoteCard.quoteGenerator[0].charge}
deleteCard={deleteCard}
moveCardDown={moveCardDown}
/>
)
default:
return null
}
}
const baseCostCard = (id) => {
setActiveCardData((activeCards) => [
...activeCards,
{
_id: id,
quoteGenerator: [
{
cardType: "base",
},
],
},
])
cumulativeListFetch(id)
}
const datePickerCard = (id) => {
setActiveCardData((activeCards) => [
...activeCards,
{
_id: id,
quoteGenerator: [
{
cardType: "date",
},
],
},
])
cumulativeListFetch(id)
}
const timedRateCard = (id) => {
setActiveCardData((activeCards) => [
...activeCards,
{
_id: id,
quoteGenerator: [
{
cardType: "timed",
},
],
},
])
cumulativeListFetch(id)
}
const textCard = (id) => {
setActiveCardData((activeCards) => [
...activeCards,
{
_id: id,
quoteGenerator: [
{
cardType: "text",
},
],
},
])
cumulativeListFetch(id)
}
const selectCard = (id) => {
setActiveCardData((activeCards) => [
...activeCards,
{
_id: id,
quoteGenerator: [
{
cardType: "select",
selectOptions: [],
},
],
},
])
cumulativeListFetch(id)
}
const checkboxCard = (id) => {
setActiveCardData((activeCards) => [
...activeCards,
{
_id: id,
quoteGenerator: [
{
cardType: "check",
},
],
},
])
cumulativeListFetch(id)
}
const numberCard = (id) => {
setActiveCardData((activeCards) => [
...activeCards,
{
_id: id,
quoteGenerator: [
{
cardType: "number",
},
],
},
])
cumulativeListFetch(id)
}
const sliderCard = (id) => {
setActiveCardData((activeCards) => [
...activeCards,
{
_id: id,
quoteGenerator: [
{
cardType: "slider",
},
],
},
])
cumulativeListFetch(id)
}
const moveCardDown = (id) => {
let oldArray = []
oldArray.push(cumulativeList)
let index = oldArray[0].indexOf(id)
let newArray = oldArray[0].filter((card) => {
return card !== id
})
newArray.splice(index + 1, 0, id)
setCumulativeList(newArray)
reorderActiveCardsDown(index)
}
const displayExtraModal = () => {
if (activeCardData.length > 0) {
return (
<NewCardModal
baseCostCard={baseCostCard}
datePickerCard={datePickerCard}
timedRateCard={timedRateCard}
textCard={textCard}
selectCard={selectCard}
checkboxCard={checkboxCard}
numberCard={numberCard}
sliderCard={sliderCard}
/>
)
}
}
const reorderActiveCardsDown = (index) => {
setActiveCardData((oldArray) => {
let newArray = Array.from(oldArray) //create a fresh array from the current one
console.log(oldArray)
const swapPositions = (array, a, b) => {
;[array[a], array[b]] = [array[b], array[a]]
}
swapPositions(newArray, index, index + 1)
return newArray
})
}
const deleteCard = (id) => {
setCumulativeList((cumulativeList) => [
...cumulativeList.filter((card) => {
return card !== id
}),
])
removeFromCumulativeList(id)
}
const removeFromCumulativeList = () => {
let quoteGeneratorTemplate = {
quoteGenerator: cumulativeList,
}
fetch(`/api/autoquotegenerators/${_id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
body: JSON.stringify(quoteGeneratorTemplate),
})
.then((response) => response.json())
.then((data) => {
console.log("Updated:", data)
})
.catch((error) => {
console.error("Error:", error)
})
}
const makeNumber = () => {
Math.floor(Math.random() * 10000)
}
const cumulativeListFetch = (id) => {
setCumulativeList((cumulativeList) => [...cumulativeList, id])
}
const cumulativeListPut = () => {
let quoteGeneratorTemplate = {
quoteGenerator: cumulativeList,
}
fetch(`/api/autoquotegenerators/${_id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
body: JSON.stringify(quoteGeneratorTemplate),
})
.then((response) => response.json())
.then((data) => {
console.log("Updated:", data)
})
.catch((error) => {
console.error("Error:", error)
})
}
return (
<Container className="d-flex flex-column justify-content-center">
<NewCardModal
baseCostCard={baseCostCard}
datePickerCard={datePickerCard}
timedRateCard={timedRateCard}
textCard={textCard}
selectCard={selectCard}
checkboxCard={checkboxCard}
numberCard={numberCard}
sliderCard={sliderCard}
/>
{activeCardData.map((card) => {
const currCard = mapQuoteCard(card)
return <div key={makeNumber()}>{currCard}</div>
})}
{displayExtraModal()}
</Container>
)
}
export default AqgSetup2
Hope это окончательное решение, и теперь все будет работать!