Home > Back-end >  React class component button setState sorting not working as intended
React class component button setState sorting not working as intended

Time:02-24

import AuthorSidebar from "../SubPages/AuthorSidebar";
import ReactPaginate from 'react-paginate';
import { Card, Button } from 'react-bootstrap';

export default class Author extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            author: [],
            AuthorTempState: [],
            selectedPage: 0,
            Postsperpage: 4,
            PagesVisited: 0
        }
        this.handlePageClick = this.handlePageClick.bind(this);


    }

    async recievedData() {

        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)

        this.setState({
            author: data.results,
            AuthorTempState: data.results
        });

    }



    componentDidMount() {


        if (localStorage.getItem('authors')) {
            this.setState({
                author: JSON.parse(localStorage.getItem('authors')),
                AuthorTempState: JSON.parse(localStorage.getItem('authors'))
            })
        } else {
            this.recievedData();
        }
    }

    componentDidUpdate(prevProps, prevState) {
        if (this.state.author !== prevState.author) {
            localStorage.setItem('authors', JSON.stringify(this.state.author))
        }


    }





    favBttn(Auth) {

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

        Auth.idfav = true;

        const updateAuthor = [Auth, ...filterData];

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

        this.setState({
            author: updateAuthor
        });

    }

    remfavBttn(Auth) {


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

        Auth.idfav = false;

        const updateAuthor = [Auth, ...filterData]

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

        this.setState({
            author: updateAuthor
        });

    }




    handlePageClick = (e) => {

        const SelectedPage = e.selected;
        const Offset = SelectedPage * this.state.Postsperpage;

        this.setState({
            selectedPage: SelectedPage,
            PagesVisited: Offset
        }, () => {
            this.recievedData();
        });
    };



    render() {



        const { author } = this.state;
        const PageCount = Math.ceil(author.length / this.state.Postsperpage);

        console.log(author)
        let sliced = author.slice(this.state.PagesVisited, this.state.PagesVisited   this.state.Postsperpage);

        return (

            <div className="AppWhole">
                <AuthorSidebar />
                <div className="App">
                    <div className="author">
                        {sliced.map(
                            (Author) => (
                                <div key={Author._id}>
                                    <Card style={{ margin: 20 }} border="dark" bg="light" text="grey">
                                        <Card.Body>
                                            <Card.Title>Name: {Author.name}
                                                {
                                                    (Author.idfav) ? (<Button size="sm" className='right' onClick={() => 
                                                        this.remfavBttn(Author)
                                                    }>Remove Favt.</Button >) : (<Button size="sm" className='right' onClick={() => 
                                                        this.favBttn(Author)
                                                    }>Add Favt.</Button >)
                                                }
                                            </Card.Title>
                                            <Card.Text>
                                                Bio: {Author.bio}
                                            </Card.Text>
                                        </Card.Body>
                                        <Card.Footer>Wiki: <a href='{Author.link}'>{Author.link}</a></Card.Footer>
                                    </Card>


                                </div>
                            ))}

                        <div >
                            <ReactPaginate
                                pageCount={PageCount}
                                onPageChange={this.handlePageClick}
                                previousLabel={"<<"}
                                nextLabel={">>"}
                                containerClassName={'paginationLinks'}
                                disabledClassName={'paginationDisabled'}
                                activeClassName={'paginationActive'}
                            />
                        </div>
                    </div>
                </div>
            </div>
        );
    }
}

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.stack.imgur.com/QitTe.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 after clicking once on a card to remove fav and then clicking another card also to remove favourite the former card gets turned to add favourite automatically.

Please help me I have been stuck on this for 2 weeks now. Thank you.

CodePudding user response:

Since you need to update a single object in-place in a list, here's how you do that really simply.


const bttn = (idfav) => Auth => this.setState({
  author: this.state.author.map(a => 
    a._id === Auth._id
      // When we find the auth to update, change its idfav
      ? {...a, idfav }
      : a
  });
const favBttn = bttn(true);
const remfavBttn = bttn(false);

  • Related