Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add forward ref to React SVG Component #5457

Merged
merged 7 commits into from
Feb 14, 2019
Merged

Conversation

GasimGasimzada
Copy link
Contributor

This pull request adds "ref" option to SVGR loader; so that, the root svg component ref can be accessed. The way it works is that SVGR creates a forward ref and passed the ref to svg component using svgRef prop.

Example:

import React, { Component } from 'react';
import { ReactComponent as Logo } from './logo.svg'; // CRA default logo file

class App extends Component {
    myRef = React.createRef();

    componentDidMount() {
        console.log(this.myRef);
    }

    render() {
        return (<Logo svgRef={this.myRef} />);
     }
}

This example will print the svg element.

Testing

I have added unit tests to webpack/SVGComponent.js; however, I was not able to perform the test. yarn e2e:docker -- --test-suite kitchensin kept giving me permission denied error inside the container.

@facebook-github-bot
Copy link

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need the corporate CLA signed.

If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks!

@iansu
Copy link
Contributor

iansu commented Oct 17, 2018

This looks good. I think we just need to get the tests passing.

@GasimGasimzada
Copy link
Contributor Author

Okay. Then, I’ll try to figure out how to perform the tests and fix if there are any problems.

@GasimGasimzada
Copy link
Contributor Author

There was a need to update Jest file transform for SVG to include ref via svgRef prop. Also some additional fixes were necessary. I still was not able to get yarn e2e:docker working to test it in my own environment. The error says permission denied on some integrity related package (I think it was node integrity).

@Timer Timer requested a review from gaearon October 17, 2018 12:23
Copy link
Contributor

@gaearon gaearon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't need a separate prop for this. Instead there should be a way to tell svgr to use React.forwardRef which does the same thing directly for the ref attribute.

@GasimGasimzada
Copy link
Contributor Author

GasimGasimzada commented Oct 17, 2018

Adding “ref” option to SVGR webpack config does add forwardRef to the SVG component. However, the prop that is being used to pass ref is svgRef when SVGR component is imported. That’s not something that I assigned. I have looked into SVGR docs to change the name to ref but I it is hard coded in their codebase.

@gaearon
Copy link
Contributor

gaearon commented Oct 17, 2018

I don't quite understand what it means. The sole purpose of forwardRef is to allow you to use ref attribute. It doesn't let you do anything else.

@iansu
Copy link
Contributor

iansu commented Oct 17, 2018

I think ref points to the React component that svgr returns, which wraps an svg element that is pointed to by svgRef. So just using ref would give you the wrapper component, not the svg itself.

@GasimGasimzada
Copy link
Contributor Author

To be completely honest, I dont quiet understand it either. I tried to use ref in CRA and kept getting error that stateless components cannot have refs; they should be assigned to elements. This is after forward ref is enabled and is the default export when SVGs are being imported using SVGR (I printed the imported component and it does have ref). However, using svgRef works fine.

I might be missing something here and I’ll investigate to see what the issue might be.

@gaearon
Copy link
Contributor

gaearon commented Oct 17, 2018

Where does svgr use forwardRef? Maybe their usage is incorrect.

@GasimGasimzada
Copy link
Contributor Author

This is the template directory for SVGR Transform: https://github.com/smooth-code/svgr/tree/master/packages/core/src/templates

util.js is where forwardRef is implemented + the reactDOMTemplate.js for the main template.

@gaearon
Copy link
Contributor

gaearon commented Oct 17, 2018

Apparently it was added specifically for a library called react-native-svg which is where the svgRef convention comes from. :-/ gregberge/svgr@4bdd989

@neoziro Can we make the solution generic so it works with ReactDOM? Ideally it's react-native-svg that should be fixed to use forwardRef instead of having its own "svgRef" prop.

@gregberge
Copy link

@gaearon the latest version of SVGR supports forwardRef but it is not supported by the version used in create-react-app. It is nothing relative with "react-native-svg", it is just a feature to enable "ref", I don't do anything different for native.

You can try it here in https://svgr.now.sh/.

@gregberge
Copy link

@gaearon if you want to upgrade SVGR, you should probably wait for the next version. I will change a lot of things:

  • Use rehype instead of JSDOM
  • Replace h2x by Babel
  • Do not include "prettier" and "svgo" by default

So it will result by a huge performance improvement and a smaller package size.

I plan to release it in one or two weeks.

@GasimGasimzada
Copy link
Contributor Author

I completely forgot about checking what version the ref was added to SVGR and got confused why ref was not working :/ Upgrading locally to v3.1.0 worked fine with. I modified the test files to use refs instead of svgRef and added forward ref to the SVG transform for Jest. However, the packages are not upgraded; so, the tests are failing (locally everything works as expected).

@iansu
Copy link
Contributor

iansu commented Oct 18, 2018

@neoziro This is good to know. I was considering updating CRA to use SVGR 3 but now I'll wait for the new version to be released. Thanks!

@stale
Copy link

stale bot commented Nov 17, 2018

This pull request has been automatically marked as stale because it has not had any recent activity. It will be closed in 5 days if no further activity occurs.

@stale stale bot added the stale label Nov 17, 2018
@iansu iansu removed the stale label Nov 17, 2018
@iansu iansu added this to the 2.1.x milestone Nov 17, 2018
@gregberge
Copy link

@iansu any update?

@iansu
Copy link
Contributor

iansu commented Nov 19, 2018

There's a PR to upgrade to SVGR 4: #5816. I think it makes sense to merge that first and then update and merge this branch.

@GasimGasimzada
Copy link
Contributor Author

@iansu Any update on this?

@iansu
Copy link
Contributor

iansu commented Feb 13, 2019

@GasimGasimzada Now that SVGR has been upgraded you should be able to update this branch. A few things have changed, for example our webpack config is now in a single file instead of separate dev and prod files. Once your branch is updated and everything is working we should be able to merge this.

@iansu iansu self-assigned this Feb 13, 2019
@GasimGasimzada
Copy link
Contributor Author

@iansu Great! I will make my changes by tomorrow then :)

@GasimGasimzada
Copy link
Contributor Author

I have updated SVGR configuration in the new webpack config.

@iansu iansu merged commit 319cf9b into facebook:master Feb 14, 2019
@iansu
Copy link
Contributor

iansu commented Feb 14, 2019

Thanks!

@lock lock bot locked and limited conversation to collaborators Feb 19, 2019
@iansu iansu modified the milestones: 2.1.x, 2.1.6 Mar 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants