0

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
Nick McLean
  • 601
  • 1
  • 9
  • 23

1 Answers1

0

Your problem is, that you are mutating state by accident. Seems like React chooses not to rerender your component in this case, so reorderActiveCardsDown still has the old data.

Also you are storing instances of your functions inside the components, which are in state, so the functions won't have the new state inside them. (only components in the return rerender)

To fix this, you should use an updater function, so you always use the latest state.

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

If you set a new state based on the previous value, you should always use an updater, so modify all your other functions accordingly.

You should never store component instances (f ex <MyComponent myProp={value} />) in state, because then the props won't update at all and you endup with weird side-effects like the ones you could experience here. In order to avoid this, I replaced activeCards with activeCardData, which stores only the data required for the mapQuoteCard function, which produces the final component instance that should be rendered.

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 this is the final solution and everything will work now!

Adam Jeliński
  • 1,708
  • 1
  • 10
  • 21
  • Hmm... Just tried that! I console.log oldArray and activeCards and still get empty arrays. – Nick McLean Apr 09 '20 at 13:31
  • You also have a problem with how you are generating your `activeCards`. The components that you have inside still have the old `moveCardDown` functions. I'll try to fix that. – Adam Jeliński Apr 09 '20 at 13:37
  • Hmm. The moveCardDown() re-orders the state called cumulativeList. This is the list that gets saved to the database. Then it calls reorderActiveCardsDown() to re-order the cards on the current screen. Thanks for your help! I look forward to learning about how to make this better! – Nick McLean Apr 09 '20 at 13:52
  • @NickMcLean Modified my answer to a solution that should work now! – Adam Jeliński Apr 09 '20 at 14:19
  • Wow! Ok! This is definantly going in the right direction. Now I hit the button, and the activeCards reorder. If I hit the button again, to swap the order one more time... it doesnt work. Is this what you mean when you say the components dont have access to the new state? – Nick McLean Apr 09 '20 at 14:41
  • Yes this must be the case. The components are swapped, but then they probably loose some important part of the data, that allows then to know which ids to swap, or something like that. I'll refactor your code and make a proper solution then :) – Adam Jeliński Apr 09 '20 at 14:47
  • I'll be workin on it myself as well. Thanks so much for your help - I had it down when I was working with class based stuff. Now I gota get used to the hooks. -- The id's in cumulativeList are swapping fine still which is good. I found out that if I try to swap back again, it adds an "undefined" to the array (on the second swap). I added an if statement so far to get this fixed. It at least prevents the code from adding the undefined. -- if(index + 1 !== newArray.length){ swapPositions(newArray, index, index + 1); } – Nick McLean Apr 09 '20 at 15:02
  • I made some significant changes to the code (and autoformatted it ;) ), so feel free to ask for any clarifications – Adam Jeliński Apr 09 '20 at 15:24
  • Thanks Adam! It works great now! I see what we are doing... I think! Instead of storing the components in the state we are storing the information for each component in the state - then in the render, it calls a function to get that information and convert it to the cards using the new switch function. Wow! I didn't know that it isn't good to store components in state...agh! Thanks so much! I just started learning javascript in February so this is great! – Nick McLean Apr 09 '20 at 15:44
  • Those are exactly the changes I made :). That's quite an advanced component, so congratulations for understanding React an JS so quickly! I recommend using Prettier to deal with code formatting, because it's much easier to read then. And I wouldn't mind if you accepted the answer, if it works :D – Adam Jeliński Apr 09 '20 at 15:57
  • Hey Adam! Just found a new problem with my code above and I am unsure how to fix it. I was wondering if you had any ideas. Everything works as it should right now - but.. I hit the re-order button and the card moves on the screen. It saves the new position and data to the database and reorders the card. Though, the issue is when a user types in new information, it is set in the state of the card. If the re-order happens, it erases what the user has entered in the card. – Nick McLean Apr 12 '20 at 00:52
  • @NickMcLean This question got quite crowded, I think you should ask a new one for the new issue and link it here, so I can help too :) – Adam Jeliński Apr 12 '20 at 10:14
  • Hey Adam! I am having another react issue dealing with sending props to a component - Here is the link - maybe you can help? https://stackoverflow.com/questions/61489514/send-component-new-props-react-stuck – Nick McLean Apr 28 '20 at 20:48