0

I'm pretty new to React and JS, and I'm having trouble calling a function in my component with a button click. I want to call the sort function with a click event on my button, but right now the sort function is being called immediately after render. How can sort onClick with my button. Any help would be appreciated. Thanks!

import React, { Component } from "react";
import { connect } from "react-redux";
import { fetchCards } from "../actions/cardActions";
import Card from "../components/Card";

class CardList extends Component {
  componentDidMount() {
    this.props.fetchCards();
  }

  sortCards = cards => {
    cards.sort(function(a, b) {
      return a.front > b.front;
    });
  };

  render() {
    const cards = this.props.cards;
    return (
      <div className="CardList">
        <button onClick={this.sortCards(cards)}>Sort Cards</button>
        {cards.map(card => (
          <Card
            key={card.id}
            cardId={card.id}
            front={card.front}
            back={card.back}
          />
        ))}
      </div>
    );
  }
}

const mapStateToProps = state => {
  return {
    cards: state.card.all
  };
};

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    fetchCards: () => {
      dispatch(fetchCards(ownProps.deckId));
    }
  };
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(CardList);
Tholle
  • 108,070
  • 19
  • 198
  • 189
mossexploding
  • 121
  • 1
  • 1
  • 6
  • 3
    `onClick={() => this.sortCards(cards)}` – Keith Mar 06 '19 at 15:25
  • or `onClick={this.sortCards.bind(null, cards)}` – Mihai Matei Mar 06 '19 at 15:26
  • Though @Keith is right he doesn't really give an explanation. The thing is, in your code, you are calling the code upon rendering, what you would rather want to do is assign an eventhandler to the click event instead, this can be done through arrow functions, through binding. You probably would would keep a local state of the sorted cards in that case, since you only receive the cards, you are not really owner of the data in that case, or you should handle sorting through some of your actions in the state itself – Icepickle Mar 06 '19 at 15:29
  • Thanks. This solution does seem to stop the automatic sort. However, now the sort function doesn't work at all. Just below the button, I'm mapping over the cards and passing them as props to a child component. Is there a way to get this is re-render with the sorted cards? Thanks! – mossexploding Mar 06 '19 at 15:29
  • You will find the sort function does indeed work, but React will not know about it. Your not using `setState` so React will not know it needs to re-render. – Keith Mar 06 '19 at 15:33
  • I see. In this case, state is being managed through Redux. Is there a way a can handle the re-render that way? Thanks for your help Keith. – mossexploding Mar 06 '19 at 15:34
  • I don't use Redux, but there should be something in the state management you attach too, that informs React of state changes. In the mean time as a temporary fix to show the sort you can force the update yourself. -> https://reactjs.org/docs/react-component.html#forceupdate – Keith Mar 06 '19 at 15:39

0 Answers0