1

I am making a image viewer in reactjs. Actually I want when a user click on a rotate icon the image is rotate about 90 deg. All thing is going well but main problem is like when I click on any image and rotate it and close it and after that if I opens other it takes the previous rotation value but it must be zero as I initializes.

class GalleryModal extends React.Component {
        constructor(props) {
          super(props);
          this.state = {
            rotation: 0
          };
          this.rotate = this.rotate.bind(this);
          this.fullScreen = this.fullScreen.bind(this);
        }

        render() {
          const { rotation } = this.state;
          if (this.props.isOpen === false) {
            return null;
          }

          return (
            <div className="modal-overlay" name={this.props.name}>
              <div className="modal-body" id="image_container">

                <img
                  className="center_image"
                  id="image"
                  src={this.props.src}
                  style={{ transform: `rotate(${rotation}deg)` }}
                />
                <a href="#" className="fullscreen button" onClick={this.fullScreen}>
                    <i className="fas fa-compress-arrows-alt"></i>
                </a>
                <a href="#" className="button" onClick={() => this.rotate()}>
                  <i className="fas fa-sync-alt" />
                </a>
                <a href="#" className="button" onClick={this.props.onPrev}>
                  <i className="fas fa-angle-left" />
                </a>
                <a href="#" className="button" onClick={this.props.onNext}>
                  <i className="fas fa-angle-right" />
                </a>
                <a
                  className="modal-close"
                  href="#"
                  onClick={this.props.onClick}
                >
                  <span className="fa fa-times" />
                </a>

              </div>
            </div>
          );
        }
        rotate() {
          let newRotation = this.state.rotation + 90;
          if (newRotation >= 360) {
            newRotation = -360;
          }
          this.setState({
            rotation: newRotation
          });
        }

        fullScreen() {
          let elem = document.getElementById("image_container");
          if (elem.requestFullscreen) {
            elem.requestFullscreen();
          } else if (elem.mozRequestFullScreen) {
            /* Firefox */
            elem.mozRequestFullScreen();
          } else if (elem.webkitRequestFullscreen) {
            /* Chrome, Safari & Opera */
            elem.webkitRequestFullscreen();
          } else if (elem.msRequestFullscreen) {
            /* IE/Edge */
            elem.msRequestFullscreen();
          }
        }
      }

Demo here This is what I tried so for but it is taking the previous value when I click another image or next/prev icon but rotation must be zero as I declared rotation:0 . I doesn't know from where the rotation error is arrised as I think i did it correct.Can you please tell me what I am doing wrongand How to solve it????

2 Answers 2

3

The problem is that, when you set the state having rotation: 0, you are modifying the state of the Gallery component; thus, when you open the model, Gallery Component has its own this.state.rotation variable set to 0.

Instead, the rotation that is used to show the image is the one in GalleryModal Component, which is never set to 0 again.

A solution could be to pass the this.state.rotation variable from Gallery Component to GalleryModal Component.

There it is your fiddle fixed: https://jsfiddle.net/3hywna07/

Furthermore, at line 61, instead of writing:

<a href="#" className="button" onClick={() => this.props.rotate()}>

Just write:

<a href="#" className="button" onClick={this.props.rotate}>

Using arrow function inside the render() method should be avoided because it would led to the creation of the function each time the render() method is executed.

update link:- https://jsfiddle.net/c0qpk5wv/2/

Sign up to request clarification or add additional context in comments.

7 Comments

when I clicking on the next and prev then the value of rotation must be again zero but in this it is taking the previous value. so I passed this.setState({ rotation: 0 }); . Is there any standard that use setState as minimum as we can?@matteo
Not sure I've understood what you meant: if you open the modal, rotation the image, than go to the next/previous image, you want the next/previous image to have rotation equal to 0? If so, at line 190 and 196 you need to change the this.setState() function so that it sets the rotation to 0.. This way! this.setState({ pointer: newPointer, rotation: 0 }); I'm also editing the JSFiddle just in case
Sorry, you edited your question right before my answer.. My comment do resolve your problem, but I don't understand what you mean with "Is there any standard that use setState as minimum as we can?"
Actually I mean that .... is there any restriction that use setState function as minimum as you can. In other word using of function setState more times is a good practice?@matteo
Well.. I think you could say that React is based on that function: every change on the UI should come from a change on the state (e.g. when you hover a button and its color became lighter, that should come from a change of the state, thus a setState call). There is no "minimum" or "maximum", because you should call it every time you need a change (and, in your case, the rotation is totally a change, so it's good.. the fact that you go to the "next/previous" image is a change, so again it's good). You just be sure that you don't end up in a setState() loop otherwise your App will crash
|
0

Matteo got it right. You could also let the modal itself keep the rotation and create a close function which will set rotation to 0 before calling the supplied close function. Gallery shouldn't be interested in the rotation as there is little value in keeping rotation between images.

Comments

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.