3

I have a table rendered with react (about 100 rows), but I would like the effect of the rows appearing one by one. Is there a way to do this with React? Below is my React code (the derivePairs funtion on the willMount procedure comes up with the data for the table).

var columns = [
      { key: 'pairNo', label: 'Zaporedna številka' },
      { key: 'homeTeam', label: 'Domača ekipa' },
      { key: 'awayTeam', label: 'Gostujoča ekipa' },
      { key: 'score', label: 'Rezultat' }
  ];

  var Table = React.createClass({

      getInitialState: function() {
        return {data: this.props.data};
      },

      componentWillMount: function() {
        derivePairs();
      },

      render: function() {
          var headerComponents = this.generateHeaders(),
              rowComponents = this.generateRows();

          return (
              <table>
                  <thead>{headerComponents}</thead>
                  <tbody>{rowComponents}</tbody>
              </table>
          );
      },

      generateHeaders: function() {
          var cols = this.props.cols;  // [{key, label}]

          // generate our header (th) cell components
          return cols.map(function(colData) {
              return <th key={colData.key}>{colData.label}</th>;
          });
      },

      generateRows: function() {
          var cols = this.props.cols,  // [{key, label}]
              data = this.props.data;

          var round=1;
          var pairNo=1;
          var oldRound=0;
          var teamName=null;
          return this.state.data.map(function(item, i) {
              // handle the column data within each row
              var htmlExcerpt = null;
              var len = Object.keys(cols).length;
              if (oldRound !== item.round) {
                  i=i+1;
                  htmlExcerpt = <tr key={'round'+item.round}><td colSpan={len}>Round: {item.round}</td></tr>;
                  oldRound = item.round;
              }
              var cells = cols.map(function(colData) {
                  console.log(colData);
                  // colData.key might be "firstName"
                  if (colData.key == "pairNo") {
                    return (<td> {pairNo} </td>);
                  } else {
                    if (colData.key == "homeTeam" || colData.key == "awayTeam") {
                      teamName = config.teams[item[colData.key]].name;
                      return (<td> {teamName} </td>);
                    } else {
                      return (<td> {item[colData.key]} </td>);
                    }
                  }
              });
              if (htmlExcerpt !== null) {
                return [htmlExcerpt,<tr className=enter-data key={i}> {cells} </tr>];
              } else {
                return <tr className=enter-data key={i}> {cells} </tr>;
              }
              pairNo=pairNo+1;
          });
      }
  });

  ReactDOM.render(<Table cols={columns} data={config.pairs}/>, document.getElementById('roundPairs'));

Thanks for the help.

1 Answer 1

2

You can achieve this by using ReactCSSTransitionGroup package.

Your render method should be like this:

// ...

render: function() {
    var headerComponents = this.generateHeaders(),
        rowComponents = this.generateRows();

    return (
        <table>
            <thead>{headerComponents}</thead>
            <ReactCSSTransitionGroup
              transitionName="fade"
              transitionEnterTimeout={500}
              transitionLeaveTimeout={300}
              transitionAppearTimeout={500}
              transitionAppear={true}
              component="tbody"
            >
              {rowComponents}
            </ReactCSSTransitionGroup>
        </table>
    );
},

// ...

Next, you should define css classes. For fade animation name, they should be:

.fade-enter {
  opacity: 0.01;
}

.fade-enter.fade-enter-active {
  opacity: 1;
  transition: opacity 500ms ease-in;
}

.fade-leave {
  opacity: 1;
}

.fade-leave.fade-leave-active {
  opacity: 0.01;
  transition: opacity 300ms ease-in;
}

.fade-appear {
  opacity: 0.01;
}

.fade-appear.fade-appear-active {
  opacity: 1;
  transition: opacity .5s ease-in;
}
Sign up to request clarification or add additional context in comments.

11 Comments

Thanks for helping, but even after doing so it's still just showing up without any fade effects. The table just instantly appears. Please check it out at: bobr.si/react/index_new.html
@Bostjan, it's looks like you haven't wrapped rows with ReactCSSTransitionGroup component. It's difficult to understand, not seeing your current code. Could you upload it on pastebin.com?
Thanks for being so helpful...I've also uploaded the code to pastebin: pastebin.com/dWnay05w althought you can also see it in the source code of that link I posted in my first comment
This solution might also work in your case. The issue is the same - how to animate elements one after the other in the initial render.
@Bostjan, sorry, initially I forgot to add transitionAppearTimeout and transitionAppear props to ReactCSSTransitionGroup. Also, you should add corresponding classes. See updated answer.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.