0

I have next and previous buttons and I want to traverse some images. When the user chooses next or previous I want the parent component to know about it. My problem is that I can't seem to catch the onChange event from the child component img element. The image changes by updating the img src attribute.

It might be worth noting that if I do <img onchange=alert('heelo') /> the alert fires correctly.

I have the following 2 components:

Child component:

var ImageViewer = React.createClass({
    getInitialState: function () {
        return {
            pages: [],
            currentPage: 0,
            imagePath: ""            
        };
    },
    handleImageLoad: function (event) {
        console.log("Image load event fired -->", event.target.tagName);        
        //this.setState({                
        //    currentPage: this.props.document.currentPage
        //}, function () {
        //    console.log("Current Page state is set");
        //    console.log(this.state.currentPage);                    
        //});

    },   
    errorLoadingImage: function (event) {
        console.log("Image load error event -->", event.target.tagName);
        console.log("pathname : " + window.location.pathname);
        var loginPath = window.location.pathname.split('/');        
        if (loginPath.length > 1) {
            //   window.location.replace("/" + loginPath[1]);
            window.location.replace(window.location.pathname);
        } else {
            console.log("Error: Can not redirect user to login path");
            console.log("window.location : " + window.location);
            console.log("window.location.pathname : " + window.location.pathname);
        }
    },
    getImageSrc: function () {
        var imagePath = this.props.document.ImageRoute,
            imageDirectory = imagePath.substring(0, imagePath.lastIndexOf('/') + 1);
        console.log("Image source from page : " +this.state.currentPage);
        //current page state gets update in prev and next events.
        var fileName = this.props.document.Pages[this.state.currentPage].FileName;
        console.log(fileName);
        console.log("loading file : " + imageDirectory + fileName);
        return (imageDirectory + fileName);
    },
    handleChange: function (event) {
        this.props.callback(event.target.value);
    },
    renderImage: function () {  
        if (this.props.document == null) {
            return <img src='' />;
        } else {            
            return <img className="imageDisplay" src={this.getImageSrc()} onChange={this.handleChange.bind(this)} onLoad={this.handleImageLoad} onError={this.errorLoadingImage}/>;
        }
    },
    render: function () {
        console.log("rendering image viewer")
        console.log("document is " + this.props.document)
        return (
            <div onClick={this.clickHandler}>              
                {this.renderPager()}     
                {this.renderImage()}                                                     
            </div>
        );
    }
});

Parent component:

var Workstation = React.createClass({
    getInitialState: function () {
        return {
            documentsInQueue: this.props.documentList,
            ImageSrc: this.props.imgSrc,
            currentDocument: null,
            currentPage : 0
        };
    },
    selectedDocument: function (document, clickedDocumentIndex) {
        console.log("selected document is :");
        console.log(document);
        console.log("clicked document index is :");
        console.log(clickedDocumentIndex);
        this.setState({ currentDocument: document }, function () {
            console.log("Image Route state is set")
            console.log(this.state.currentDocument.ImageRoute)
        });
    },
    onImageViewerPageChange: function (event) {
        console.log("current page from event : " + currentPage);
        this.setState({ currentPage: currentPage }, function () {
            console.log("Workstation: Current Page state is set")
            console.log(this.state.currentPage)
        });
    },
    render: function () {
        return (
            <div className="container-fluid">
                <div className="row">
                    <div className="document col-md-2 border-outline">
                        <DocumentQueue initialData={this.state.documentsInQueue} imgSrc={this.state.ImageSrc} selectedDocument={this.selectedDocument} currentPage={this.state.currentPage}/>
                    </div>
                    <div className="col-md-2 border-outline">                        
                        <Indexing document={this.state.currentDocument} />                                                          
                    </div>
                    <div className="col-md-8 border-outline imageViewer">
                        <ImageViewer document={this.state.currentDocument} callback={this.onImageViewerPageChange}/>                        
                    </div>
                </div>
            </div>
        );
    }
});
3
  • how does an img change? Commented Dec 7, 2015 at 17:12
  • I update the img src. Commented Dec 7, 2015 at 17:25
  • 1
    that should fire onload, but i've never heard of onchange firing from an img before... Commented Dec 7, 2015 at 17:32

1 Answer 1

2

Theoretical answer:

this.imageUrl = this.getImageSrc();
if this.previousUrl != this.imageUrl {
    this.handleChange.bind(this);
}
this.previousUrl = this.imageUrl;
return <img className="imageDisplay" src={this.imageUrl} onLoad={this.handleImageLoad} onError={this.errorLoadingImage}/>;

You may want to set state as a result of getImageSrc function and use that state in the view, and also move change checking logic into getImageSrc. So it re-renders the view properly

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

2 Comments

thats a great idea. This is along the lines of the reactjs guidelines for boolean shouldComponentUpdate( object nextProps, object nextState ) However, i feel i was being verbose and i should be able to make onload work.
Well, if you execute that getImageSrc only if relevant prop changed should increase performance in case you have other props that may change. And if you re-save state, it will trigger the view rerender.

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.