Expo web - Render app inside a phone mockup - react-native

Hello I am currently building an app that has a web version for some users and I am trying to render the whole app inside an iPhone mockup on web only.
An example of what I want can be found here: https://i.stack.imgur.com/xpTer.png
I found that I can integrate the <body></body> tag inside of an iframe which worked but the styles were not applied. What I did was this:
iframe.tsx
function IFrame({ children }) {
const [ref, setRef] = useState();
const container = ref?.contentDocument?.body;
return (
<iframe title="iframe" ref={setRef}>
{container && createPortal(children, container)}
</iframe>
);
}
App.tsx
export default function App() {
return (
<IFrame>
<MyComponent />
</IFrame>
);
}
Thanks to anyone who can help me :)

Related

React Native app with react-hook-form not working (View config getter callback form component 'input' must be a function (received 'undefined')

I'm creating a mobile app with React Native and I need to use a form. I want to use react-hook-form, but I can't get it to work, even in a newly created project. I did the following:
Created new React Native projects: it runs as it should
npm install react-hook-form
copy-paste following code to App.js:
import React from "react";
import { useForm } from "react-hook-form";
export default function App() {
const { register, handleSubmit, watch, formState: { errors } } = useForm();
const onSubmit = data => console.log(data);
console.log(watch("example")); // watch input value by passing the name of it
return (
/* "handleSubmit" will validate your inputs before invoking "onSubmit" */
<form onSubmit={handleSubmit(onSubmit)}>
{/* register your input into the hook by invoking the "register" function */}
<input defaultValue="test" {...register("example")} />
{/* include validation with required or other standard HTML validation rules */}
<input {...register("exampleRequired", { required: true })} />
{/* errors will return when field validation fails */}
{errors.exampleRequired && <span>This field is required</span>}
<input type="submit" />
</form>
);
}
It gives following error: screenshot of emulator
I have no idea what's the problem. Is there something wrong with the installation of react-hook-form as it doesn't recognize the input field?
Thanks!

Why don't WebView script injections work?

this document suggests that I should be able to inject values into a web page displayed by the WebView component such that the value can be used by loaded the page:
https://github.com/react-native-community/react-native-webview/blob/master/docs/Guide.md#communicating-between-js-and-native
specifically, the code below shows how to set a value within the window object but does not show how it is used:
import React, { Component } from 'react';
import { View } from 'react-native';
import { WebView } from 'react-native-webview';
export default class App extends Component {
render() {
const runFirst = `
window.isNativeApp = true;
true; // note: this is required, or you'll sometimes get silent failures
`;
return (
<View style={{ flex: 1 }}>
<WebView
source={{uri: 'my-url-here'}}
injectedJavaScriptBeforeContentLoaded={runFirst}
/>
</View>
);
}
}
the page I'm loading looks like this:
<html>
<body>
<script>
alert(window.isNativeApp)
</script>
</body>
</html>
which displays undefined. I've also tried:
<html>
<body>
<script>
var fn = function() {
alert(window.isNativeApp)
}
document.addEventListener('DOMContentLoaded', fn, false)
</script>
</body>
</html>
with identical results. given that I'm supposed to be able to send the webpage values, how am I supposed to use them?
from my package.json:
"react-dom": "~16.9.0",
"react-native": "^0.62.1",
"react-native-webview": "^8.2.1",
Appendix I
in fact, the above doesn't seem to run at all. if I try the following:
const runFirst = `
console.log('INJECTION')
alert('INJECTION')
true; // note: this is required, or you'll sometimes get silent failures
`;
I get neither an alert, nor a trace in the log. of course, I'm not sure whether alert() can work before the document is loaded, or whether the log would be visible to me in the regular app's console output
by contrast injectedJavaScript does seem to run, albeit after the document loads, which means that at the time that the <script> in my doc runs, the value hasn't yet been set
for the next poor sod that struggles with this, the library is broken and will (someday) be fixed, but in the meantime, this works:
<WebView
source={{uri: 'my-url-here'}}
injectedJavaScriptBeforeContentLoaded={runFirst}
onMessage={event => { alert(event.nativeEvent.data )}}
/>
the onMessage is intended for communications in the other direction but its mere presence makes the code work

How to allow the props of every component to be defined in one central place in react native?

the question is clear. I think it can be done with react native elements. But how? I am very new to react native.
I read the documentation in here. It has a code like this:
import { ThemeProvider, Button } from 'react-native-elements';
const theme = {
Button: {
raised: true,
},
};
// Your App
const App = () => {
return (
<ThemeProvider theme={theme}>
<Button title="My Button" />
<Button title="My 2nd Button" />
</ThemeProvider>
);
};
What if this part of the code:
const theme = {
Button: {
raised: true,
},
};
was coded in another file. How will I make the buttons raised?
You have 2 ways to aboard your problem.
First, if you want to use the same style for your react-native-elements components across certain files and they are all the children of the same parent file, you use this bit of code :
<ThemeProvider theme={theme}>
<Button title="My Button" />
<Button title="My 2nd Button"/> // ... plus any other component that contains your react native elements components
</ThemeProvider>
for this case if you want to put your config variable in another file , you can do it like this :
create a new file that contains your config variable let say for example a new file called config.js
// config.js file
export default {
Button:{
raised:true
}
// ... other RN-elements props
}
// or this
const theme = {
Button: {
raised: true,
},
}
export {theme}
then import it in your workspace like so :
// the file were you are using your themeProvider
import theme from "path_to_your_config.js_file"
// or respectively
import {theme} from "path_to_your_config.js_file"
// then use the variable theme as you like
the second way is that you create your own custom component and you style it however you want and you use it in your app.

How to open external link in browser from inside Webview in React Native?

I have below webview component, I wanted the link to be opened in a mobile browser app rather than in inside current webview in my app.
return() {
<WebView source={{ html: `Google`}} />
}
This worked for me.
import { WebView, Linking, NavState } from 'react-native';
const html = `
Google
Twitter
`
class WebViewWrapper extends Component {
private webview;
handleNavigationStateChange = (event: NavState) => {
if (event.url) {
this.webview.stopLoading();
Linking.openURL(event.url);
}
};
render() {
return (
<WebView
originWhitelist={['*']}
ref={ref => {
this.webview = ref;
}}
source={{ html }}
onNavigationStateChange={this.handleNavigationStateChange}
/>
);
}
}
you can do this:
import { Linking } from 'react-native';
on you launch function
Linking.openURL( some_url );
For more details, follow this full example: Just what you want
Calling stopLoading freezes the WebView and links may stop working after pressing them once. Better to use onShouldStartLoadWithRequest (API Reference).
So the code could look something like this:
import { Linking } from 'react-native';
import { WebView } from 'react-native-webview';
const html = `
Google
Twitter
`;
const shouldStartLoadWithRequest = (req) => {
// open the link in native browser
Linking.openURL(req.url);
// returning false prevents WebView to navigate to new URL
return false;
};
const MyComponent = () => (
<WebView
originWhitelist={['*']}
source={{ html }}
onShouldStartLoadWithRequest={shouldStartLoadWithRequest}
/>
);
export default MyComponent;
Note that onShouldStartLoadWithRequest behaves a bit differently on iOS.
Try this one. This will save your time and patience :)
import HTML from 'react-native-render-html';
<HTML
html={this.state.content.description}
// imagesMaxWidth={Dimensions.get('window').width}
onLinkPress={(evt, href) => { Linking.openURL(href) }}
/>
Fully supportive of android, ios and Expo too. And has some cool customisations you can try with.
https://www.npmjs.com/package/react-native-render-html

expected a component class, got [object Object]

I get an error with this code. However, changing to react-native's removes the error. Can you use div with react-native? If not, why is this error so obscure...?
var React = require('react');
var ReactNative = require('react-native');
var {
StyleSheet,
Text,
View,
} = ReactNative;
let Auto = React.createClass({
getInitialState: function() {
return { value: 'Ma' }
},
render: function() {
return (
<div className="fuck-react">
Blah blah blah
</div>
)
}
});
No you cannot use div tag in react-native. Since, react-native is based on JSX syntax which are automatically dispatched to native components by abstract Dom parser. you can get your answer here:https://facebook.github.io/react-native/docs/tutorial.html
Also, react-native is upadated to new version that is 0.29 , you probably should ignore old ECMA script and use new ECMA script for javascript syntax. Since, react-native uses reactjs for its javascript so better learn from here: http://reactjs.net/guides/es6.html
Instead of DIV use View.
<View style={{flex: 1}}>
<Text>Blah blah blah</Text>
</View>
You can not use in react native. Use native component instead.
<View>
<Text>text text text</Text>
</View>
Do not forget to import before with:
import {
Text,
View
} from 'react-native';
You may be using ReactJS component in a React Native App. I accidentally installed a component with <div> tags in React Native project.