Search code examples
reactjsfluxreactjs-flux

ReactJS - Showing some elements and a button to show more


I'm using React, with the Flux architecture.

In a certain part of my app, I need to show some elements (let's say, 6) and, if there's more, a button that will display the rest of them when clicked. As I'm using Flux, I want my components to be as stateless as possible. So far I've tried:

let elements = [...] //Array with elements, passed as a prop to MyApp
class MyApp extends React.Component {
...
  render(){
    var elements = this.props.elements.map((elem, i) => {
      if (i == 5)
        return <More />
      if (i > 5)
        return;
      return (
       <ShowElement key={i} />
      )

  return <div>{elements}</div>
  }
}

I think I could make this work by passing the remaining elements to my More component as prop, but it feels wrong. Is there a better way to do this?


Solution

  • As far as showing 6 items and rest when button is clicked, this is way to do it using state:

    let elements = [...] //Array with elements, passed as a prop to MyApp
    
    class MyApp extends React.Component {
    
      getInitialState() {
        return {
          all: false
        };
      },
    
      render(){
        return <div>{this._renderElements(this.props.elements, this.state.all)}</div>
      },
    
      _renderElements(elements, showAll) {
    
          const _elementsToRender = [];
          const _elements = elements.splice(0); // clone array
          let remainder = [];
    
          if (!showAll) {
            remainder = _elements.splice(6);
          }
    
          _elements.forEach(el => {
              _elementsToRender.push(
                  <ShowElement {..el} />
              );
          });
    
          if (remainder.length > 0) {
              _elementsToRender.push(
                    <button onClick={evt => this.setState({ all: true })}>show all</button>
              );
          }
    
          return (
              <div>
                {_elementsToRender}
              </div>
          );
      }
    }
    

    And if you want to keep your component stateless you could pass something like showAll prop and make <button> (or whatever custom element you use) trigger action that will change showAll value in store and emit new value so component updates that way.