chrvadala / react-svg-pan-zoom

:eyes: A React component that adds pan and zoom features to SVG
https://chrvadala.github.io/react-svg-pan-zoom/
MIT License
681 stars 127 forks source link

ref.current is null when use componentDidMount #133

Closed levaifelasticad closed 5 years ago

levaifelasticad commented 5 years ago

Hi, I had a problem with ref and componentDidMount. I use this code:

import React, { Component, createRef } from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import { AutoSizer } from 'react-virtualized'; import { ReactSVGPanZoom } from 'react-svg-pan-zoom'; // import { TAG_TYPES } from 'Constants/style'; import StageHandler from '../StageHandler/StageHandler.container'; // import ComponentContainer from 'Components/App/Stage/ContainerComponent'; import styles from './View.scss';

class View extends Component { constructor(props) { super(props); this.state = { percent: 100, }; this.node = createRef(); }

componentDidMount() {
    this.props.resetHandlebarPosition();
    console.log(this.node);
    this.node.current.fitToViewer();
}

onStageClick = (ev) => {
    ev.stopPropagation();
    const { target: { id } } = ev;
    this.props.setElement(id);
};

onZoomOn = async (ev) => {
    ev.stopPropagation();
    await this.node.current.zoomOnViewerCenter(1.1);
    console.log(this.node.current.getValue());
    this.setState({
        percent: Math.round(this.node.current.getValue().a * 100),
    });
}

fitToViewer = (ev) => {
    ev.stopPropagation();
    this.node.current.fitToViewer('center', 'center');
    console.log(this.node.current.getValue());
    this.setState({
        percent: Math.round(this.node.current.getValue().a * 100),
    });
}
render() {
    const { width: svgwidth, height: svgheight } = this.props.projectDimensions;
    const { percent } = this.state;
    return (
        <div
            className={styles.stageView}
            onClick={this.onStageClick}
            role="presentation"
        >
            <button className="btn" onClick={this.onZoomOn}>Zoom in</button>
            <button className="btn" onClick={this.fitToViewer}>Fit</button>
            <span>{percent}</span>
            {/* <ComponentContainer /> */}
            <AutoSizer>
                {(({ width, height }) => width === 0 || height === 0 ? null : ( // eslint-disable-line
                    <ReactSVGPanZoom
                        width={width}
                        height={height}
                        ref={this.node}
                        detectAutoPan={false}
                        toolbarPosition={'left'}
                        miniaturePosition={'left'}
                        toolbarProps={{ SVGAlignX: 'center', SVGAlignY: 'center' }}
                        background={'#f1f3f2'}
                        className={styles.viewer}
                    >
                        <svg
                            width={svgwidth}
                            height={svgheight}
                            xmlns="http://www.w3.org/2000/svg"
                            xlinkHref="http://www.w3.org/1999/xlink"
                            style={"padding-top: 15px"} // eslint-disable-line
                        >
                            <g
                                dangerouslySetInnerHTML={{ // eslint-disable-line
                                    __html: this.props.svgString,
                                }}
                            />
                        </svg>
                    </ReactSVGPanZoom>
                ))}
            </AutoSizer>
            <StageHandler />
        </div>
    );
}

}

View.propTypes = { svgString: PropTypes.string, projectDimensions: PropTypes.object, // eslint-disable-line setElement: PropTypes.func.isRequired, resetHandlebarPosition: PropTypes.func.isRequired, currentProject: PropTypes.object, // eslint-disable-line };

View.defaultProps = { svgString: null, };

export default View;

It seems than when componentDidMount is called, the component doesn't rendered to DOM, because this.node.current is null.

levaifelasticad commented 5 years ago

I resolved it with componentDidUpdate.