I am trying to get access to my state, called activeCards, from a function in a react component. I have access to it in Use Effect... but I only want the function to run if a button is pressed.
The function, reorderActiveCardsDown, takes the array from the state... and re-orderes it... and then puts the array back. It was working in my class based componenets - but I am having trouble using it with the functional based components.
I can console.log the state from useEffect, and it works fine... but if I console.log the state from the function, it is empty.
I guess my question is - do I use useEffect in this case - to pass the information back to the new function? If I wanted the function to run every time... I could just put it in useEffect.. but I only want it to run when I press that button.
Thanks!
useEffect(() => {
console.log('active cards updated')
// prints the whole array to the console.
}, [activeCards])
const reorderActiveCardsDown = () => {
let oldArray = []
console.log(activeCards)
// prints empty array to the console, hence no access to the state yet.
oldArray.push(activeCards);
console.log(oldArray[0])
const swapPositions = (array, a ,b) => {
[array[a], array[b]] = [array[b], array[a]]
}
swapPositions(oldArray[0], index, index+1);
setActiveCards(oldArray[0]);
}
Here is the full code - The component makes a fetch to my api from a single ID to get an array of IDs. That comes from function FetchIDS(). Once the array has been fetched, it is set to the cumulativeList state. Each ID fetched represents a card - that way I can let the user add or delete the cards they want.
Once the state "cumulativeList", is updated, I call convertIdToCard(), from a useEffect function. Each ID is fetches the card information and converts it to a component which is stored in the state "activeCards". convertIdToCard() fetches the card information and calls CreateQuoteCards(). CreateQuoteCards() creates the component to be added to the ActiveCards List. At the end of CreateQuoteCards(), I update the activeCardsList. The render function displays the list.
Now the user can see each card. Each card also is passed a function through props - moveCardDown(). When the user presses the button to re-order the specific card, moveCardDown() re-orders the cumulativeList (the list of ids that will be saved to the database). This works up to here. Now moveCardDown() calls the function I am having trouble with... reorderActiveCardsDown().
Here is the full code!
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 [ activeCards, setActiveCards] = 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')
}, [activeCards])
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) => {
let display = [];
if(quoteCard.quoteGenerator[0].cardType === "base"){
display.push(
<BaseCostCard id={quoteCard._id} cardTitle={quoteCard.quoteGenerator[0].cardTitle} charge={quoteCard.quoteGenerator[0].charge} deleteCard={deleteCard} moveCardDown={moveCardDown}/>
);
}else if(quoteCard.quoteGenerator[0].cardType === "date"){
display.push(
<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}/>
);
}else if(quoteCard.quoteGenerator[0].cardType === "timed"){
display.push(
<TimedRateCard id={quoteCard._id} cardTitle={quoteCard.quoteGenerator[0].cardTitle} charge={quoteCard.quoteGenerator[0].charge} deleteCard={deleteCard} moveCardDown={moveCardDown}/>
)
}else if(quoteCard.quoteGenerator[0].cardType === "text"){
display.push(
<TextCard id={quoteCard._id} cardTitle={quoteCard.quoteGenerator[0].cardTitle} charge={quoteCard.quoteGenerator[0].charge} deleteCard={deleteCard} moveCardDown={moveCardDown}/>
)
}else if(quoteCard.quoteGenerator[0].cardType === "select"){
display.push(
<SelectCard id={quoteCard._id} cardTitle={quoteCard.quoteGenerator[0].cardTitle} charge={quoteCard.quoteGenerator[0].charge} selectOptions={quoteCard.quoteGenerator[0].selectOptions}deleteCard={deleteCard} moveCardDown={moveCardDown} />
)
}else if(quoteCard.quoteGenerator[0].cardType === "check"){
display.push(
<CheckboxCard id={quoteCard._id} cardTitle={quoteCard.quoteGenerator[0].cardTitle} charge={quoteCard.quoteGenerator[0].charge} deleteCard={deleteCard} moveCardDown={moveCardDown}/>
)
}else if(quoteCard.quoteGenerator[0].cardType === "number"){
display.push(
<NumberCard id={quoteCard._id} cardTitle={quoteCard.quoteGenerator[0].cardTitle} charge={quoteCard.quoteGenerator[0].charge} deleteCard={deleteCard} moveCardDown={moveCardDown}/>
)
}else if(quoteCard.quoteGenerator[0].cardType === "slider"){
display.push(
<SliderCard id={quoteCard._id} cardTitle={quoteCard.quoteGenerator[0].cardTitle} charge={quoteCard.quoteGenerator[0].charge} deleteCard={deleteCard} moveCardDown={moveCardDown}/>
)
}
setActiveCards(activeCards => [...activeCards, display[0]])
}
const baseCostCard = (id) => {
setActiveCards(activeCards => [...activeCards, <BaseCostCard id={id} deleteCard={deleteCard} moveCardDown={moveCardDown}/> ])
cumulativeListFetch(id);
}
const datePickerCard = (id) => {
setActiveCards(activeCards => [...activeCards, <DatePickerCard id={id} deleteCard={deleteCard} moveCardDown={moveCardDown}/> ])
cumulativeListFetch(id);
}
const timedRateCard = (id) => {
setActiveCards(activeCards => [...activeCards, <TimedRateCard id={id} deleteCard={deleteCard} moveCardDown={moveCardDown}/> ])
cumulativeListFetch(id);
}
const textCard = (id) =>{
setActiveCards(activeCards => [...activeCards, <TextCard id={id} deleteCard={deleteCard} moveCardDown={moveCardDown}/> ])
cumulativeListFetch(id);
}
const selectCard = (id) =>{
setActiveCards(activeCards => [...activeCards, <SelectCard id={id} deleteCard={deleteCard} moveCardDown={moveCardDown} selectOptions={[]} /> ])
cumulativeListFetch(id);
}
const checkboxCard = (id) =>{
setActiveCards(activeCards => [...activeCards, <CheckboxCard id={id} deleteCard={deleteCard} moveCardDown={moveCardDown}/> ])
cumulativeListFetch(id);
}
const numberCard = (id) => {
setActiveCards(activeCards => [...activeCards, <NumberCard id={id} deleteCard={deleteCard} moveCardDown={moveCardDown}/> ])
cumulativeListFetch(id);
}
const sliderCard = (id) => {
setActiveCards(activeCards => [...activeCards, <SliderCard id={id} deleteCard={deleteCard} moveCardDown={moveCardDown}/> ])
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();
}
const displayExtraModal = () => {
if(activeCards.length > 0){
return <NewCardModal baseCostCard={baseCostCard} datePickerCard={datePickerCard} timedRateCard={timedRateCard} textCard={textCard} selectCard={selectCard} checkboxCard={checkboxCard} numberCard={numberCard} sliderCard={sliderCard}/>
}
}
const reorderActiveCardsDown = () => {
let oldArray = []
console.log(activeCards)
oldArray.push(activeCards);
// console.log(oldArray[0])
// const swapPositions = (array, a ,b) => {
// [array[a], array[b]] = [array[b], array[a]]
// }
// swapPositions(oldArray[0], index, index+1);
// setActiveCards(oldArray[0]);
}
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}/>
{activeCards.map(card => {
return <div key={makeNumber()}>{card}</div>
})}
{displayExtraModal()}
</Container>
)
}
export default AqgSetup2