0

I'm using Bootstrap 3 and want to clear each .row when 12 columns have been created. But my code fails, I get this error:

Failed to compile. Error in ./src/File/file.js Syntax error: Unexpected token, expected , (145:56)

In this line: { index % 4 == 0 && <div className="row"> }

const TweetImageList = ({images, removeImage}) => {
    return (
        <div className="TweetImageList">

            <ReactCSSTransitionGroup transitionName="tweetImageTransition"
                                     transitionEnterTimeout={500}
                                     transitionLeaveTimeout={500}>
                {
                    images.map((image, index) => {
                        let column =
                            <div key={index} className="col-xs-3 tweet-image-wrapper">
                                <TweetImage
                                    image={image}
                                    removeImage={removeImage}
                                />
                            </div>;

                        return column;

                    })
                }
            </ReactCSSTransitionGroup>

        </div>
    );
};

And yes, it IS necessary some times to clear the row because it's not "self clearing" like the BS docs imply. Read here: https://stackoverflow.com/a/26445839/1736012

!! UPDATE !!

I updated my jsx according to Yo Wakitas suggestion. Floats is now cleared with rows. But transitions does not work anymore... Any ideas??????

const TweetImageList = ({images, removeImage}) => {
    return (
        <div className="TweetImageList">

            {
                _.chunk(images, 4).map((chunk, i) => {
                    return (
                        <div key={i} className="row spacing-bottom">

                            {
                                chunk.map((image, j) => {
                                    return (
                                        <div key={j} className="col-xs-3">

                                            <ReactCSSTransitionGroup transitionName="tweetImageTransition"
                                                                     transitionEnterTimeout={500}
                                                                     transitionLeaveTimeout={500}>
                                                <TweetImage
                                                    image={image}
                                                    removeImage={removeImage}/>
                                            </ReactCSSTransitionGroup>
                                        </div>
                                    )
                                })
                            }

                        </div>
                    )
                })
            }
        </div>
    );
};

removeImage()

removeImage(id) {
    this.setState({
        images: this.state.images.filter(function (img) {
            return img.id !== id;
        }),
        startValue: this.state.startValue + this.numPhotoChars
    });
}
Community
  • 1
  • 1
olefrank
  • 6,452
  • 14
  • 65
  • 90

1 Answers1

1

I suggest writing it as a ternary, where if index%4 === 0, then show the row wrapped element. Otherwise, show the div without the row div.

{this.state.photos.map((image, index) => {
  const column =
    <div className="col-xs-3">
      <TweetImage 
        image={image} 
        index={index} 
        key={'image-' + index} 
        removeImage={this.removeImage}
      />
    </div>;
  return (
    index%12 === 0 
    ? <div className="row">
        {column}
      </div>
    : {column}
  );
  }
)}

Edit: based on your comment, it looks like you should chunk your this.state.photos into an array of arrays of length 4, then map over that. If you are already using lodash as a utility library, you can use the chunk function like this:

  {_.chunk(this.state.photos, 4).map((chunk, i) => 
    <div className="col-xs-3">
      {chunk.map((image, j) => 
        <TweetImage 
          image={image} 
          index={j} 
          key={'image-' + i + '-' + j} 
          removeImage={this.removeImage}
        />
      )}
    </div>
  )}

You could make your own function that partitions this.state.photos if you don't use a utility library. Theres multiple examples of that here.

Community
  • 1
  • 1
Yo Wakita
  • 5,322
  • 3
  • 24
  • 36
  • Yeah but a .row should surround 4 .col-xs-4 divs, not 1. The problem seems to be, that you can not write partial markup with JSX, only complete well-closed tags... I need to open a row every index > 0 && index%4 === 0, and then close the row again before opening new one. – olefrank Mar 24 '17 at 08:15
  • I see. I updated my answer that gives a solution for that. You can chunk your array into groups of 4, and then map over that array. – Yo Wakita Mar 24 '17 at 13:42
  • Oh wait, the transition no longer works. Any idea? I will update my jsx so you can see... – olefrank Mar 24 '17 at 16:01
  • Can you explain what you mean by no longer works? What are you expecting to happen, and what happens now? Are there any errors? – Yo Wakita Mar 24 '17 at 16:34
  • The "" part is on enter / leave transitions of the image. This is defined as css transitions in my style sheet. I didnt touch it and it worked before this markup change. Do you need more information? – olefrank Mar 24 '17 at 16:51
  • Can you include your removeImage function in your question? My hunch is that the function needs to be updated for your new mapping of data. – Yo Wakita Mar 24 '17 at 16:53
  • It's there now. I didnt touch it. The new "mapping of data"?? The images list and removeImage() is just passed down via props... RemoveImage() works perfectly BTW, removing the image. But the transition is missing.... – olefrank Mar 24 '17 at 16:57
  • The problem could be that every image is placed inside a span tag (with no width/height). React does this for some reason, I can't figure out why.. Do you know what's causing the spans? – olefrank Mar 24 '17 at 17:05
  • Can you double check that the image is actually being removed from state? It looks like you're missing `this.` Try this: `removeImage={() => this.removeImage(image)}` – Yo Wakita Mar 24 '17 at 17:07
  • Sorry I misread your component code and didnt notice it was stateless. I think it should be `removeImage={() => removeImage(image.id)}` – Yo Wakita Mar 24 '17 at 17:32
  • removeImage={() => removeImage(image.id)} does not change anything. removeImage() still works but no transition... So it seems this is not the problem... – olefrank Mar 24 '17 at 17:52
  • Oh. ReactCSSTransitionGroup is animating the wrong list...! It's animating the individial chunks of the original list "state.images". I never add/remove to the chunks, I add/remove to state.images. That's why no changes are detected and therefore no transitions occuring. At least I THINK this is the explanation... – olefrank Mar 24 '17 at 19:15