On react native I have seen 2 ways to do the export/render, what are the name of them, what other export ways are there?
one way:
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
</View>
);
}
second way:
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>MaKo Open up App.js to start working on your app!</Text>
</View>
);
}
}
First one is a functional component and the second one is a class component.
Most code use these two ways to export or render.
There have some description on document.
Related
In the below code, I expected the webView content to not change when the clicks are increased, but every time it loads, a new timestamp is displayed.
const webView = (
<WebView
source={{
uri:
'data:text/html,<html><script>document.write("<h1 style=\\"font-size:64px\\">"+Date.now()+"<h1>");</script>',
}}
/>
);
export default class App extends React.Component {
state = {
clicks: 0,
};
onClick = () => {
this.setState({ clicks: this.state.clicks + 1 });
};
render() {
return (
<View>
<Text onPress={this.onClick}>
Click Me: {this.state.clicks}
</Text>
{this.state.clicks % 2 === 0 ? webView : null}
{this.state.clicks % 2 === 1 ? webView : null}
</View>
);
}
}
Link to expo snack to check it on a device.
So far, I've read about reparenting in React on issues here, implementing using Portals, and also saw an issue on supporting reparenting in react native with no resolution.
So, how to reuse a component instance in across multiple screens with out creating a new instance of it in every screen?
Was hoping reparenting would be the answer, but can't find any implementations, so if reparenting is the answer to this, how to implement it myself?
The problem here is that on every state change your component will re-render webView object and will show the current date. I suggest that you change webView to a component and add a static key when you call WebViewComp to prevent unmount/mount on every state change.
const WebViewComp = () => ( //Change declaration to function component instead of constant object
<WebView
source={{
uri:
'data:text/html,<html><script>document.write("<h1 style=\\"font-size:64px\\">"+Date.now()+"<h1>");</script>',
}}
/>
);
export default class App extends React.Component {
state = {
clicks: 0,
};
onClick = () => {
this.setState({ clicks: this.state.clicks + 1 });
};
render() {
return (
<View style={styles.container}>
<Text style={styles.paragraph} onPress={this.onClick}>
Click Me: {this.state.clicks}
</Text>
{this.state.clicks % 2 === 0 ? <WebViewComp key="child" /> : null}
{this.state.clicks % 2 === 1 ? <WebViewComp key="child" /> : null}
</View>
);
}
}
You definitely need to reparenting the view. I searched some libs that work as React Portals does.
We have two projects available:
https://github.com/zenyr/react-native-portal
https://github.com/mfrachet/rn-native-portals
I tested the second package (rn-native-portals) and this magically worked on Android:
How to install
npm install mfrachet/rn-native-portals
react-native link (unfortunately we can't auto-link this yet, but we can submit PR)
Implementation
Your target element needs to be inside <PortalOrigin>
import React from "react";
import { View, Text, TouchableOpacity } from "react-native";
import { PortalOrigin } from 'rn-native-portals';
class Target extends React.Component {
state = {
moveView: false,
}
render() {
return (
<>
<TouchableOpacity
style={{ flex: 1 }}
onPress={() => this.setState({ moveView: !this.state.moveView })}
>
<Text>Press Here</Text>
</TouchableOpacity>
<PortalOrigin destination={this.state.moveView ? 'destinationPortal' : null}>
<View>
<Text>This text will appear on destination magically...</Text>
</View>
</PortalOrigin>
</>
);
}
}
export default Target;
On destination use this (don't forget set the same unique portal's name)
import React from "react";
import { PortalDestination } from "rn-native-portals";
class Destination extends React.Component {
render() {
return (
<PortalDestination name="destinationPortal" />
);
}
}
export default Destination;
This project is amazing, but definitely need our community help to create a better documentation.
I have one project that need to use this feature, reparenting a video to the outside of screen. I'm seriously considering PR auto-link support to avoid compiling warnings.
More useful info about:
The project concept:
https://github.com/mfrachet/rn-native-portals/blob/master/docs/CONCEPT.md
Why the project was created (long history):
https://tech.bedrockstreaming.com/6play/how-a-fullscreen-video-mode-ended-up-implementing-react-native-portals/
Haven't tried the accepted answer's projects but, for React Native, #gorhom/portal works like a charm retaining context like a champ!
Im new in react native,
before in my code using const Main = () => { ..}
but when i change to export default class Main extends React.Component { ..} , problems arise like style in View not working but the error ',' expected in style
Screnshoot :
im using new version of react native
You are missing the render() method where the return() method should be.
Ex:
export default class LotsOfStyles extends Component {
render() {
return (
<View>
<Text style={styles.red}>just red</Text>
<Text style={styles.bigBlue}>just bigBlue</Text>
<Text style={[styles.bigBlue, styles.red]}>bigBlue, then red</Text>
<Text style={[styles.red, styles.bigBlue]}>red, then bigBlue</Text>
</View>
);
}
}
from react native docs
i want to render another component in the main component so user won't face a white screen for a second!
i'm using TabNavigator from react-navigation and when i want to switch between tabs, i face a white screen for a second (seems it need a second to render).
i was thinking of rendering the second tab in the first so i can have a better user experience!
P.s. : my components are in separate files!
Main:
export default class AdCalc extends React.Component {
render() {
return (
<View>
<Text>
TEST
</Text>
</View>
);
}
}
and my child:
export default class Child extends React.Component {
render() {
return (
<View>
<Text>
This is child!
</Text>
</View>
);
}
}
thanks in advance!
You can use react-navigation TabNavigatorConfig's lazy prop. Pass lazy={false} so that your views may load at initial start. Then you will not see such a screen.
I am working on a simple calculator app to learn react native. I have a button component that displays the number buttons. I need to pass it a function so that when the button is touched the state of the parent is updated to the new number.
Without the bind(this) it says this.setState is undefined. When I add bind(this) in the constructor all I get is a blank page in my app. My code is listed below.
constructor:
constructor() {
super();
this.state = {
total: 0,
display: 0
};
this._displayUpdate = this._displayUpdate.bind(this);
}
One row of calculator buttons:
<View style={styles.buttonRow}>
<NumButton numText={7} update={this._displayUpdate} />
<NumButton numText={8} update={this._displayUpdate} />
<NumButton numText={9} update={this._displayUpdate} />
<FuncButton funcText={'*'} />
</View>
NumButton Component:
export default class NumButton extends Component {
render() {
return (
<TouchableHighlight style={styles.buttonArea} onPress={this.props.update(this.props.numText)}>
<Text style={styles.buttonText}>{this.props.numText}</Text>
</TouchableHighlight>
)
}
}
Your parent bind is right. The problem is with the onPress of the TouchableHighlight in the NumButton component. You can't add code to execute to it, You should pass a function to it. You can use ES6 arrow function:
export default class NumButton extends Component {
render() {
return (
<TouchableHighlight style={styles.buttonArea}
onPress={()=>{ this.props.update(this.props.numText) }}
>
<Text style={styles.buttonText}>{this.props.numText}</Text>
</TouchableHighlight>
)
}
}
I am trying to push a component when initial component is about to render. I am using the react-native-router-flux module. Unfortunately the Action.checkpass call does not execute while the one in Button tag does (i.e on click).
Any ideas what I could be doing wrong?
class Launch extends React.Component {
render(){
//transfer to checkpass
Actions.checkpass;
return (
<View style={styles.container}>
<Text>Launch page</Text>
<Button onPress={Actions.checkpass}>Go to Register page</Button>
</View>
);
}
};
Call Actions.route('checkpass');