Search code examples
javascriptreactjsweblocal-storageuse-effect

React.js Functional Component Localhost Problem


So my page is an Author page which shows different authors and their details in each card which I fetched from API and then mapped. https://i.sstatic.net/eSD7u.png

And in each card after onclick it changes to Remove Favourite. The card which is favourited makes the idfav true in the object array of the author state and false if not favourited. And there is a 2nd page which shows all the favourite authors. Now I am passing it down first as localstorage for the author state but it seems after my 2nd reload if I click on the button irrespective of whether or not the button is add or remove all the other cards/array is removed and only the card on which button I selected shows up.

    const [author, setAuthor] = useState([]);


    const [AuthorTempState, setAuthorTempState] = useState([]);

    // pagination calculation
    const [PageNumber, setPageNumber] = useState(0);
    const [Postsperpage] = useState(4);
    const PagesVisited = PageNumber * Postsperpage;
    const pageCount = Math.ceil(author.length / Postsperpage);
    const changePage = ({ selected }) => {
        setPageNumber(selected);
    }


    const getAuthors = async () => {

        const res = await fetch(`https://api.quotable.io/authors?limit=30`);

        const data = await res.json();


        for (const element of data.results) {
            element.idfav = false;
        }

        data.results.sort((a, b) => (a._id > b._id) ? 1 : -1)

        setAuthor(data.results);

        setAuthorTempState(data.results);


    }


    const saveAuth = () => {
        localStorage.setItem('authors', JSON.stringify(author));
    }

    const getAuth = () => {
        const newAuthors = JSON.parse(localStorage.getItem('authors'));
        if (newAuthors && newAuthors.length > 0) {
            setAuthor(newAuthors);
        } else {
            getAuthors();
        }
    }

    useEffect(() => {
        // console.log((author));

        if (author.length === 0) {
            getAuth();
        }

        saveAuth();

    }, [author]);



    const favBttn = (Auth) => {


        const filterData = AuthorTempState.filter(data => data._id !== Auth._id)

        Auth.idfav = true;

        const updateAuthor = [Auth, ...filterData]

        updateAuthor.sort((a, b) => (a._id > b._id) ? 1 : -1)


        setAuthor(updateAuthor)


    }

    const remfavBttn = (Auth) => {


        const filterData = AuthorTempState.filter(data => data._id !== Auth._id)

        Auth.idfav = false;

        const updateAuthor = [Auth, ...filterData]

        updateAuthor.sort((a, b) => (a._id > b._id) ? 1 : -1)

        setAuthor(updateAuthor);

    }

    const Author = author.slice(PagesVisited, PagesVisited + Postsperpage)



    return (
        <div className="AppWhole">
            <AuthorSidebar />
            <div className="App">
                <div className="author">
                    {Author.map(
                        (Author) => (
                            <div className="authors" key={Author._id}>
                                {
                                    (Author.idfav) ? (<button className='right' onClick={() => {
                                        remfavBttn(Author);
                                    }}>Remove Favt.</button >) : (<button className='right' onClick={() => {
                                        favBttn(Author);
                                    }}>Add Favt.</button >)
                                }
                                <p>Name: {Author.name}</p>
                                <p>Bio: {Author.bio}</p>
                                <p>Wiki: <a href='{Author.link}'>{Author.link}</a></p>
                            </div>
                        ))}

                    <div id='pageauthor'>
                        <ReactPaginate
                            pageCount={pageCount}
                            onPageChange={changePage}
                            previousLabel={"<<"}
                            nextLabel={">>"}
                            containerClassName={'paginationLinks'}
                            disabledClassName={'paginationDisabled'}
                            activeClassName={'paginationActive'}
                        />
                    </div>
                </div>
            </div>
        </div>
    );
}

export default Authors;

Please help me I have been stuck on this for a week. Thank you.


Solution

  • Okay, once I read your entire code and then read your issue made it pretty clear what's wrong. The issue is here

        const favBttn = (Auth) => {
    
            // notice that you are using AuthorTempState to filter data
            // but do you remember initialising it when the data is found in local storage?
            // AuthorTempState is currently an empty array.
            const filterData = AuthorTempState.filter(data => data._id !== Auth._id)
    
            Auth.idfav = true;
    
            const updateAuthor = [Auth, ...filterData]
    
            updateAuthor.sort((a, b) => (a._id > b._id) ? 1 : -1)
    
            setAuthor(updateAuthor)
        }