I'm struggling to get react-native-svg animate in React Native. I also tried the method they suggest with react-native-svg-transformation but it didn't suit my case since I'm working with many files and render them dynamically.
Here's my render file:
import React from "react";
import { View, Text } from "react-native";
import { SvgXml } from "react-native-svg";
import SvgAssets from "../resources/SvgAssets";
import AssetsHelper from "../common/AssetsHelper";
class ChineseCharacter extends React.Component {
constructor(props) {
super(props);
this.state = {
xmlData: "",
};
}
render() {
const { xmlData, file } = this.state;
if (xmlData.length === 0) {
return <View />;
}
return (
<View style={{ flex: 1 }}>
<SvgXml xml={xmlData} width="200" height="200" />
</View>
);
}
componentDidMount(): void {
const { character } = this.props;
const characterUnicode = character.charCodeAt(0);
const file = SvgAssets[characterUnicode.toString()];
AssetsHelper(file)
.then(result => {
this.setState({
xmlData: result,
});
})
.catch(err => console.log(err));
}
}
export default ChineseCharacter;
AssetsHelper is basically reading the svg file and convert them to string in order to pass to SvgXml.
SvgAssets is an object with key as the charCode and value is the file, something like this:
const assets = {
"11904": require("./svgs/11904.svg"),
...
}
Thank in advance.
After few struggling hours, I have found a work around for this problem. I don't use react-native-svg anymore, instead I parse the .svg file to string and put it in react-native-webview. Work like a charm!
render() {
// #ts-ignore
const { xmlData, file } = this.state;
if (xmlData.length === 0) {
return <View />;
}
return (
<View style={{ width: 300, height: 300 }}>
<WebView
source={{ html: xmlData }}
style={{ backgroundColor: "transparent", width: 300, height: 300 }}
/>
</View>
);
}
Try to import the svg files inside ChineseCharacter class.
import svgXml11904 from './svgs/11904.svg'
const assets = {
"11904": svgXml11904,
...
}
Related
I want to know the URL every time it changes in Webview. I searched online a lot. And according to that, I have done these changes. But it is still not working.
What am I doing wrong here. Why its not working.
It only logs for the first time. or it works when I click some other button on the screen.
What am I missing?
import React, { Component } from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { WebView } from 'react-native-webview';
const initialUrl = 'https://www.youtube.com/';
let url = '';
class App extends Component {
state = {
url: initialUrl,
};
onNavigationStateChange = navState => {
console.log("navstate=== ",navState)
if (url!==navState.url) {
url = navState.url;
alert(url);
this.setState({
url: url
})
}
};
render() {
const { url } = this.state;
const injectedJs = `
var linkElements = document.getElementsByTagName("a");
linkElements[0].addEventListener("click", function() {
window.postMessage("addAccountSuccess?token=abc1234");
});
linkElements[1].addEventListener("click", function() {
window.postMessage("addAccountError");
`;
return (
<View style={{paddingTop: 24, flex: 1}}>
<Text style={{backgroundColor: 'black', color: 'white'}}>{ url }</Text>
<WebView
style={{ flex: 1}}
source={{
uri: initialUrl,
}}
injectedJavaScript={injectedJs}
startInLoadingState
scalesPageToFit
javaScriptEnabledAndroid={true}
javaScriptEnabled={true}
domStorageEnabled
startInLoadingState={false}
onNavigationStateChange={this.onNavigationStateChange.bind(this)}
onMessage={event => {
alert('MESSAGE >>>>' + event.nativeEvent.data);
}}
onLoadStart={() => {
console.log("LOAD START ");
}}
onLoadEnd={() => {
console.log('LOAD END');
}}
onError={err => {
console.log('ERROR ');
console.log(err);
}}
/>
</View>
);
}
}
export default App;
I am trying to implement a code that tests the internet connectivity using react native NetInfo from '#react-native-community/netinfo'. It is giving me an error that says "Can't find variable: connectionStatus". I tried my best declare properly but for some reason it is giving the error above.
import React, { Component } from 'react'
import NetInfo from '#react-native-community/netinfo';
import { ActivityIndicator, StyleSheet,View, Text } from 'react-native'
import { WebView } from 'react-native-webview';
export default class BrowserScreen extends Component {
constructor(props) {
super(props);
this.state = {
connectionStatus: false,
}
}
componentDidMount() {
const {navigation} = this.props;
this.focusListener = navigation.addListener('didFocus', () => {
this.checkConnected();
})
}
async checkConnected() {
const networkState = await NetInfo.fetch();
if (networkState.isConnected) {
this.setState({ connectionStatus: true });
}
}
LoadingIndicatorView() {
return <ActivityIndicator
color='#009b88'
size='large'
style={styles.ActivityIndicatorStyle}
/>
}
render() {
let url = this.props.navigation.getParam('webUrl');
console.log(url) ;
return (
/**
* use the webview here to display the webpage
*/
connectionStatus ? (
<WebView
source={{ uri: url }}
renderLoading={this.LoadingIndicatorView}
startInLoadingState={true}
/>
) :
(
<View>
<Text> No Connection !!!!</Text>
</View>)
)
}
}
const styles = StyleSheet.create({
ActivityIndicatorStyle: {
flex: 1,
justifyContent: 'center'
}
})
connectionStatus is stored in state, refer to it as this.state.connectionStatus
I created a simple app, that shows a few pictures with titles. It is something like a film gallery, where you can observe all enable films. But when I try to add ScrollView element it doesn't work when I try to scroll on my emulated Android device. How can I fix it? My code looks like this:
import React, { Component } from 'react'
import { View, ScrollView, StyleSheet } from 'react-native'
import { Header, ImageCard } from './src/components/uikit'
const url = 'https://s3.eu-central-1.wasabisys.com/ghashtag/RNForKids/00-Init/data.json'
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
title: 'STAR GATE',
data: []
};
}
componentDidMount = async () => {
try {
const response = await fetch(url)
const data = await response.json()
this.setState({ data })
}
catch (e) {
console.log(e)
throw e
}
}
render() {
const { title, data } = this.state
const { container } = style
return (
<View>
<Header title={title} />
<ScrollView>
<View style={container}>
{
data.map(item => {
return <ImageCard data={item} key={item.id} />
})
}
</View>
</ScrollView>
</View>
)
}
}
const style = StyleSheet.create({
container: {
marginTop: 30,
flexDirection: 'row',
flexWrap: 'wrap',
flexShrink: 2,
justifyContent: 'space-around',
marginBottom: 150
}
})
I made it with a guide, so it should work. (Youtubes author hasn't this problem on his video).
The View inside ScrollView looks problematic. Try something like:
<ScrollView contentContainerStyle={container} >
{
data.map(item => {
return <ImageCard data={item} key={item.id} />
})
}
</ScrollView>
I'm trying to inject a splash screen image on to my app but I keep getting error message: RangeError: Maximum call stack size exceeded Project is react-native-cli, could that be the issue?
import React, { Component } from 'react';
import { Image, View } from 'react-native';
import { inject } from 'mobx-react';
#inject("stores")
export default class SplashScreen extends Component {
constructor(props) {
super(props)
}
componentDidMount() {
const { stores, navigation } = this.props;
setTimeout (() => {
navigation.navigate("Login")
}, stores.config.SplashTime)
}
render() {
const { stores } = this.props
return (
<View style={{flex: 1}}>
<Image style={{flex: 1, width: null, height: null}} source={stores.config.SplashIMG}/>
</View>
)
}
}
Changed img link to require and amended component to DidUpdate.
componentDidUpdate() {
const { stores, navigation } = this.props;
console.log(this.props)
setTimeout (() => {
navigation.navigate("Login")
}, stores.config.SplashTime)
}
render() {
const { stores } = this.props
return (
<View style={{flex: 1}}>
<Image style={{flex: 1, width: null, height: null}} source={require('../../images/splash.jpg')}/>
</View>)
}
}```
I'm having trouble updating my WebView values based on user input in React Native. I'm trying to make charts in WebView using D3.js, and the chart displayed is depending on user input.
Here is an example of my problem, the HTML times clicked is not being updated. I have tried using .reload() on webview ref also, but this just gives me a blank html instead.
// #flow
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,
View,
Image,
Text,
TouchableHighlight,
WebView
} from 'react-native';
export default class WebViewTest extends Component {
constructor(props) {
super(props);
this.state = {
timesClicked : 0
};
this._onPressButton = this._onPressButton.bind(this);
this.generateJSCode = this.generateJSCode.bind(this);
}
_onPressButton() {
let timesClicked = this.state.timesClicked++;
console.log(timesClicked + " Clicked ");
this.setState({
timesClicked: this.state.timesClicked++
});
}
generateJSCode() {
console.log("Times clicked: " + this.state.timesClicked);
let jsCode = `document.getElementById("content").innerHTML = "HTML Times clicked: ${this.state.timesClicked}";`;
return jsCode;
}
render() {
let html = `
<div id="content">
This is my name
</div>
`;
return (
<View style={styles.container}>
<TouchableHighlight onPress={this._onPressButton}>
<Text>Press me to increase click</Text>
</TouchableHighlight>
<Text>React Native times clicked: {this.state.timesClicked}</Text>
<WebView
style={styles.webView}
source={{html : html}}
injectedJavaScript={this.generateJSCode()}
javaScriptEnabledAndroid={true}
>
</WebView>
</View>
);
}
}
let styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
margin: 30
},
webView: {
backgroundColor: '#fff',
height: 350,
}
});
I was able to do this using messages instead of injected javascript. I would like to recommend people to just use a library such as victory-charts or use react-art to render svg paths instead, as webviews are just not optimal for this type of problem (d3 charts in React Native).
// #flow
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,
View,
Image,
Text,
TouchableHighlight,
WebView
} from 'react-native';
export default class WebViewTest extends Component {
constructor(props) {
super(props);
this.state = {
timesClicked : 0
};
this._onPressButton = this._onPressButton.bind(this);
}
_onPressButton() {
let timesClicked = this.state.timesClicked;
timesClicked++;
console.log(timesClicked + " Clicked ");
this.setState({
timesClicked: timesClicked
});
this.refs.myWebView.postMessage("This is my land times " + timesClicked);
}
render() {
let html = `
<div id="content">
This is my name
</div>
<script>
document.addEventListener('message', function(e) {
document.getElementById("content").innerHTML = e.data;
});
</script>
`;
return (
<View style={styles.container}>
<TouchableHighlight onPress={this._onPressButton}>
<Text>Press me to increase click</Text>
</TouchableHighlight>
<Text>React Native times clicked: {this.state.timesClicked}</Text>
<WebView
style={styles.webView}
source={{html : html}}
ref="myWebView"
javaScriptEnabledAndroid={true}
onMessage={this.onMessage}
>
</WebView>
</View>
);
}
}
let styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
margin: 30
},
webView: {
backgroundColor: '#fff',
height: 350,
}
});