react-native-svg
react-native-svg copied to clipboard
SvgUri example as given in README.md crashes in Expo Web
Bug
I created a fresh expo app using expo init app-simple
using the Typescript template. Added the SvgUri example.
Resulted in the following error in my console:
(I have to add, the standard Expo <Image> component supports svg if you install react-native-svg. If not, it will skip svg files without warning.)
index.js:1 Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `App`.
at App
at ExpoRootComponent (http://localhost:19007/static/js/bundle.js:8361:83)
at div
at http://localhost:19007/static/js/bundle.js:46754:25
at div
at http://localhost:19007/static/js/bundle.js:46754:25
at AppContainer (http://localhost:19007/static/js/bundle.js:38675:24)
console.<computed> @ index.js:1
react-dom.development.js:25058 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `App`.
at createFiberFromTypeAndProps (react-dom.development.js:25058:1)
at createFiberFromElement (react-dom.development.js:25086:1)
at createChild (react-dom.development.js:13446:1)
at reconcileChildrenArray (react-dom.development.js:13719:1)
at reconcileChildFibers (react-dom.development.js:14125:1)
at reconcileChildren (react-dom.development.js:16990:1)
at updateHostComponent (react-dom.development.js:17632:1)
at beginWork (react-dom.development.js:19080:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:3945:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:3994:1)
at invokeGuardedCallback (react-dom.development.js:4056:1)
at beginWork$1 (react-dom.development.js:23964:1)
at performUnitOfWork (react-dom.development.js:22776:1)
at workLoopSync (react-dom.development.js:22707:1)
at renderRootSync (react-dom.development.js:22670:1)
at performSyncWorkOnRoot (react-dom.development.js:22293:1)
at scheduleUpdateOnFiber (react-dom.development.js:21881:1)
at updateContainer (react-dom.development.js:25482:1)
at react-dom.development.js:26021:1
at unbatchedUpdates (react-dom.development.js:22431:1)
at legacyRenderSubtreeIntoContainer (react-dom.development.js:26020:1)
at render (react-dom.development.js:26103:1)
at renderApplication (renderApplication.js:23:1)
at Object.run (index.js:49:1)
at Function.runApplication (index.js:93:1)
at registerRootComponent (registerRootComponent.tsx:14:1)
at Module../node_modules/expo/AppEntry.js (AppEntry.js:5:1)
at __webpack_require__ (bootstrap:789:1)
at fn (bootstrap:100:1)
at Object.1 (tracing.js:7:1)
at __webpack_require__ (bootstrap:789:1)
at bootstrap:856:1
at bootstrap:856:1
Environment info
Run react-native info
in your terminal and copy the results here. Also, include the precise version number of this library that you are using in the project
React native info output:
System:
OS: macOS 12.3.1
CPU: (10) arm64 Apple M1 Pro
Memory: 387.34 MB / 32.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 16.14.0 - /opt/homebrew/opt/node@16/bin/node
Yarn: 1.22.17 - /opt/homebrew/bin/yarn
npm: 8.3.1 - /opt/homebrew/opt/node@16/bin/npm
Watchman: 2022.02.21.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.11.2 - /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 21.4, iOS 15.4, macOS 12.3, tvOS 15.4, watchOS 8.5
Android SDK: Not Found
IDEs:
Android Studio: 2021.1 AI-211.7628.21.2111.8193401
Xcode: 13.3/13E113 - /usr/bin/xcodebuild
Languages:
Java: 17.0.2 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 17.0.1 => 17.0.1
react-native: 0.64.3 => 0.64.3
react-native-macos: Not Found
npmGlobalPackages:
*react-native*: Not Found
Library version: 12.1.1 (preferred by expo install, but same thing happend with 12.3.0)
Steps To Reproduce
Issues without reproduction steps or code are likely to stall.
- expo init app-simple (use typescript template)
- cd app-simple
- yarn add react-native-svg
- copy the example code for SvgUri into App.tsx
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.tsx to start working on your app!</Text>
<SvgUri
// style={styles.image}
width="100%"
height="100%"
uri="http://thenewcode.com/assets/images/thumbnails/homer-simpson.svg"
/>
<StatusBar style="auto" />
</View>
);
}
Describe what you expected to happen:
I was expecting the app to show Homer. But it crashed and showed the above error instead.
I have the same issue. Took forever to track here.
@raarts Have you found any workaround?
And can you explain what you mean by:
I have to add, the standard Expo component supports svg if you install react-native-svg. If not, it will skip svg files without warning.
I tried to show a list of remote images using FlatList
and the Image
component. This worked, except for the svg images.
To Solve this I tried to detect (by file extension) what the image type was, and use the appropriate component to display the image. That's when I found out about the crashing.
Later on I found out that if react-native-svg is installed the Image component will support svg. So, that's what I ended up doing.
I tried to show a list of remote images using
FlatList
and theImage
component. This worked, except for the svg images. To Solve this I tried to detect (by file extension) what the image type was, and use the appropriate component to display the image. That's when I found out about the crashing.Later on I found out that if react-native-svg is installed the Image component will support svg. So, that's what I ended up doing.
I have react-native-svg installed but Image component still doesn't render svg images.
Did you still have to import { Svg } from 'react-native-svg';
?
This is my Image component:
<Image
source={{
uri: icon,
}}
/
Any idea why it's not working?
No, I have no idea why it's not working, but are you sure you use uri properly? Mine is a http:// URL.
No, I have no idea why it's not working, but are you sure you use uri properly? Mine is a http:// URL.
Mine is https:// URL.
Yes, it's corrent, I can see the SVG in DevTools inspect, when viewing in Expo Web:
<img alt="" draggable="false" src="https://res.cloudinary.com/dresqigku/image/upload/v1650007219/general_6d3491bccd.svg" class="css-accessibilityImage-9pa8cd">
There's no error, it just doesn't show anything.
When viewing in Expo iOS, it gives console warning:
"Failed prop type: Invalid prop 'source' supplied to 'Image', expected one of type [number, number].
Are you sure all you had to do is install react-native-svg for Image component to be able to accept SVG?
This is how I do it:
<Image
style={styles.image}
source={{ uri: API_SERVER_URL + `/v1/s3/download?id=${item.id}` }}
resizeMode="contain"
/>
I'm pretty sure I only needed to install react-native-svg. Maybe the remote server needs to send the 'Content-Type': 'image/svg+xml' ? Mine does.
Hi everyone, any idea when it is going to be fixed? Using Image works for me on the web, but not on iOS (have not tried Android)
I have the same bug. The only solution to display SVGs is either to use react-native Image
, or if you wish to have your svg properly rendered to <svg>
and stylable use Svg, Path, ..
and construct it yourself. I guess that could be automated, but still a pain :/
Same issues here, anybody making progress on this?
Same issue here.
Same issues here, anybody making progress on this?
Same issue
SvgUri
does not seem to be implemented/supported for the web.
Here is a very quick fix that I have hacked together. There is probably a better way to do it.
Inside of node_modules/react-native-svg/lib/module/ReactNativeSVG.web.js
or node_modules/react-native-svg/lib/commonjs/ReactNativeSVG.web.js
(depending on which module you are using) add this:
export async function fetchText(uri) {
const response = await fetch(uri);
if (response.ok || response.status === 0 && uri.startsWith('file://')) {
return await response.text();
}
throw new Error(`Fetching ${uri} failed with status ${response.status}`);
}
export function SvgUri(props) {
const { onError, uri, onLoad, fallback } = props;
const [xml, setXml] = React.useState(null);
const [isError, setIsError] = React.useState(false);
React.useEffect(() => {
uri
? fetchText(uri)
.then((data) => {
setXml(data);
isError && setIsError(false);
onLoad?.();
})
.catch((e) => {
onError(e);
setIsError(true);
})
: setXml(null);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [onError, uri, onLoad]);
if (isError) {
return fallback ?? null;
}
if (!xml) {
return fallback ?? null;
}
const encoded = encodeSvg(xml);
return createElement("img", { src: "data:image/svg+xml," + encoded });
}
I have placed it after the function measureLayout
at the line 160, but it should work elsewhere.
You should save your patch with patch-package
afterwards.
Hello @airowe @raarts @tmountain, It should work now. But if you are still having that problem, please don't hesitate to let us know. here is an example of how you can check that problem:
import {View, Text} from 'react-native';
import {SvgUri} from 'react-native-svg';
export default function App() {
return (
<View style={{flex: 1, backgroundColor: 'purple'}}>
<Text>Open up App.tsx to start working on your app!</Text>
<SvgUri
width="100%"
height="100%"
uri="https://upload.wikimedia.org/wikipedia/commons/7/73/Ruby_logo.svg"
/>
</View>
);
}
Thank you.