React Navigation pass navigation prop - react-native-navigation

According to the react navigation docs the navigation prop gets passed when you select a screen from the stack navigator.
In example if I have two routes registered:
HomeScreen
Details
export default class HomeScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Button
onPress={() => this.props.navigation.navigate('Details')}>
<Text>Press me</Text>
</Button>
</View>
);
}
}
Simple enough! However let us suppose I had another component being called:
export default class HomeScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<MyOtherComponent />
</View>
);
}
}
and I would like this:
<Button
onPress={() => this.props.navigation.navigate('Details')}>
<Text>Press me</Text>
</Button>
to be in , how would I do this?
Would I pass the prop from HomeScreen to MyOtherComponent?

I actually found the answer in the docs. For anyone else this might help that didn't go through all the docs like me.
I can use withNavigation
In the example of MyOtherComponent I can do the following:
import { withNavigation } from 'react-navigation';
class MyOtherComponent extends React.Component {
render stuff here
}
export default withNavigation(MyBackButton);

Related

How to convert 'Functional Componenet' to 'Class Component' in React in Material-UI

I.e. I want to use this Material-UI example as Class Component. How?
import React from 'react';
import Button from '#material-ui/core/Button';
import Menu from '#material-ui/core/Menu';
import MenuItem from '#material-ui/core/MenuItem';
export default function SimpleMenu() {
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = event => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<div>
<Button aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick}>
Open Menu
</Button>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
</div>
);
}
It raised many error, so I removed 'const', but still getting many issues.
I don't know why would you want to convert a functional component into a class based one (usually goes the other way around). But it goes something like this
import React from 'react';
import Button from '#material-ui/core/Button';
import Menu from '#material-ui/core/Menu';
import MenuItem from '#material-ui/core/MenuItem';
export default class SimpleMenu extends React.Component {
state = {
anchorEl: null
}
handleClick = event => this.setState({ anchorEl: event.currentTarget })
handleClose = () => this.setState({ anchorEl: null })
render() {
const { anchorEl } = this.state
return (
<div>
<Button aria-controls="simple-menu" aria-haspopup="true" onClick={this.handleClick}>
Open Menu
</Button>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={this.handleClose}
>
<MenuItem onClick={this.handleClose}>Profile</MenuItem>
<MenuItem onClick={this.handleClose}>My account</MenuItem>
<MenuItem onClick={this.handleClose}>Logout</MenuItem>
</Menu>
</div>
);
}
}
Notice that useState is a hook which isn't supported in class based components, you must use classic this.state and this.setState instead. Don't forget about this before calling your handlers: this.handleClick

Unhandled Rejection (UnknownErrorException): The API version "2.0.91" does not match the Worker version "1.10.97"

Got this error while trying to add PDF file into my website locally.
I have create one component called 'ViewPDF.jsx' and code for 'ViewPDF.jsx' is:
import React, { Component } from "react";
import { Page } from "react";
import { Document } from 'react-pdf/build/entry.webpack';
import PDF from 'react-pdf-js';
import { Resume } from '../Download/Resume.pdf';
class ViewPDF extends React.Component {
constructor(props) {
super(props);
this.state = {
page: 0,
pages: 2
};
this.onDocumentComplete = this.onDocumentComplete.bind(this);
this.onPageComplete = this.onPageComplete.bind(this);
}
onDocumentComplete(pages) {
this.setState({ page: 1, pages });
}
onPageComplete(page) {
this.setState({ page });
}
render() {
return (
<div>
<PDF file="{Resume}"/>
</div>
);
}
}
export default ViewPDF;
And I have created page under src/screen/Contact.jsx
Code for 'Contact.jsx' is:
import React, { Component } from "react";
import Navbar from "../components/Navbar.jsx";
import Footer from "../components/Footer.jsx";
import Jumbotron from "../components/Jumbotron.jsx";
import { Document } from "react-pdf";
import ViewPDF from "../components/ViewPDF.jsx";
class Contact extends Component {
render() {
return (
<div>
<Navbar />
<Jumbotron title="welcome" subtitle="put something" />
<div className="container">
<h2>Contact Me</h2>
<p>
Email Address:
<a
href="mailto:abc4#gmail.com?Subject=Hello"
target="_top"
>
Click here for my Email Address
</a>
</p>
<p>
Click here for my resume!
resume
</p>
<ViewPDF />
</div>
<Footer />
</div>
);
}
}
export default Contact;
My PDF file is saved locally under src/Download/Resume.pdf.
I am newbie to React. When I open page in Chrome I got this error message:
Unhandled Rejection (UnknownErrorException): The API version "2.0.91" does not match the Worker version "1.10.97"
Thank you in advance!

Route Param not working with React

I am trying to use Route params but I cannot get the params.
The page simply shows nothing, seems like undefined or blank.
How do I get the param from "wedding/:pageName"?
What is missing here? Is it the best way to get params?
The "pageName" is not ID, is it a problem?
Thanks in advance
My App.js
import React, { Component } from 'react';
import { BrowserRouter, Route } from 'react-router-dom';
import { connect } from 'react-redux';
import * as actions from '../actions';
import Header from './Header';
import Weddings from './Weddings';
class App extends Component {
render() {
return (
<div className="container">
<BrowserRouter>
<div className="container">
<Header />
<Route path="/wedding/:pageName" component={Wedding} />
</div>
</BrowserRouter>
</div>
);
}
}
export default connect(null, actions)(App);
Wedding.js
import React from 'react';
import WeddingPage from './weddings/WeddingPage';
const Wedding = () => {
return (
<div>
<WeddingPage />
</div>
);
}
export default Wedding;
WeddingPage.js
import React, { Component } from 'react';
class WeddingPage extends Component {
render() {
return (
<div>
{this.props.pageName}
</div>
);
}
}
export default WeddingPage;
It's because you aren't passing props through from Wedding to WeddingPage.
Wedding.js needs to accept and pass props to it's child:
import React from 'react';
import WeddingPage from './weddings/WeddingPage';
const Wedding = props => {
return (
<div>
<WeddingPage {...props} />
</div>
);
}
export default Wedding;
WeddingPage.js:
import React, { Component } from 'react';
class WeddingPage extends Component {
render() {
return (
<div>
{this.props.match.params.pageName}
</div>
);
}
}
export default WeddingPage;
With react router, you can access the router params as this.props.match.params.pageName
In your case, first you need to get pageName params in Wedding component like
this.props.match.params.pageName
and than further pass pageName props to weddingPage component like <WeddingPage pageName={this.props.match.params.pageName} />

ReactJS Error : Only one default export allowed per module

This multiple component doesn't work;
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, Link, browserHistory, IndexRoute } from 'react-router'
class App extends React.Component {
render() {
return (
<div>
<ul>
<li><Link>Home</Link></li>
</ul>
{this.props.children}
</div>
)
}
}
export default App;
class Home extends React.Component {
render() {
return (
<div>
<h1>Home...</h1>
</div>
)
}
}
export default Home;
ReactDOM.render((
<Router history = {browserHistory}>
<Route path = "/" component = {App}>
<IndexRoute component = {Home} />
<Route path = "home" component = {Home} />
</Route>
</Router>
), document.getElementById('app'))
It give a below error;
ERROR in ./main.js Module build failed: SyntaxError:
C:/Users/hasithay/Desktop/reactApp/main.js: Only one default export
allowed per module.
31 | } 32 |
33 | export default Home;
| ^ 34 | 35 | class About extends React.Component { 36 | render() {
# multi main webpack: bundle is now VALID
Answer should be three clickable links that can be used to change the route When the app is started.
Multiple component does work but you need to export the component with name and you can only export one default component.
Like in below expample I export the App Component as defalut component and other component Home, About, Contact as a named component.
For the named component you need to import them using there name :
import {Home,About,Contact} from './App.jsx';
import default component:
import App from './App.jsx';
import React from 'react';
import {Link} from 'react-router';
class App extends React.Component {
render() {
return(
<div>
<ul>
<li><Link to="home">Home</Link></li>
<li><Link to="about">About</Link></li>
<li><Link to="contact">Contact</Link></li>
</ul>
{this.props.children}
</div>
)
}
}
export default App;
export class Home extends React.Component {
render() {
return (
<h1>Home Page Content</h1>
)
}
}
export class About extends React.Component {
render() {
return (
<h1>About Page Content</h1>
)
}
}
export class Contact extends React.Component {
render() {
return (
<h1>Contact Page Content</h1>
)
}
}
import React from 'react';
import ReactDOM from 'react-dom';
import {Router, Route, browserHistory, IndexRoute} from 'react-router';
import App from './App.jsx';
import {Home,About,Contact} from './App.jsx';
ReactDOM.render((
<Router history = {browserHistory}>
<Route path = "/" component = {App}>
<IndexRoute component = {Contact} />
<Route path = "home" component = {Home} />
<Route path = "about" component = {About} />
<Route path = "contact" component = {Contact} />
</Route>
</Router>
), document.getElementById('app'));
Don't import default component (App Component) with the name component (Home, About, Contact). if you import them with the named component they didn't render properly.
Blockquote
import React from 'react';
import {Link} from 'react-router';
class App extends React.Component {
render() {
return(
<div>
<ul>
<li><Link to="home">Home</Link></li>
<li><Link to="about">About</Link></li>
<li><Link to="contact">Contact</Link></li>
</ul>
{this.props.children}
</div>
)
}
}
export default App;
export class Home extends React.Component {
render() {
return (
<h1>Home Page Content</h1>
)
}
}
export class About extends React.Component {
render() {
return (
<h1>About Page Content</h1>
)
}
}
export class Contact extends React.Component {
render() {
return (
<h1>Contact Page Content</h1>
)
}
}
you have one line with the code:
export default App;
After some other lines you have the code:
export default Home;
That's just the problem! you have used export default 2 times in one file. you have to change one of them to solve the problem.
"you cannot use export default more than one time in a file".
export all the components in one line
export default {App, Home, Contacts, About};
Export Default Home is used to Expose any module to use in other files, but only one component is a default not all. A module can only be exported once. You are using the same statement to export each component which is unnecessary.
Importing components using this statement
import {Home,About,Contact} from './App.jsx';
You need to remove default keywords on both App and Home classes, as per code below:
export App;
export Home;
default keywords is only use when you want to export ONE class.

Redux Form : How to add function after validation success and before submit

I have a redux form that have a validation. When the validation returns with no errors, it will by default submit to the controller in the handleSubmit().
class SomeComponent extends Component {
constructor(props) {
super(props)
}
render() {
const { handleSubmit, fields: { field }, submitting, values } = this.props;
return (
<form onSubmit={handleSubmit(this.props.someActionForm)}>
<TextField {...field.input}
type="text"
label="FIELD"
floatingLabelText="FIELD"
errorText={field.touched? field.error: null}
/>
<div className="col-xs-12">
<FlatButton
label="ACTIVATE"
fullWidth={true}
style={styles.fullButton}
backgroundColor="#4FCDCC"
hoverColor="#59e5e3"
type="submit"
disabled={submitting}
/>
</div>
</form>
);
}
}
function validate(values) {
const errors = {};
if(!values.field) {
errors.field= "Field must not be empty !!!";
}
return errors;
}
SomeComponent = reduxForm({
form: "SomeComponent",
fields: ['field'],
validate
}, mapStateToProps, mapDispatchToProps )(SomeComponent);
How can I add a function, for example a loading element to be triggered when the validation is successful but before the form submits to the action (handleSubmit())?
Thank you in advance
You can add a class method like this:
class SomeComponent extends Component {
submit(formProps) {
// your logic
this.props.someActionForm(formProps);
};
render() {
const {handleSubmit, fields: {field}, submitting, values} = this.props;
return (
<form onSubmit={handleSubmit(this.submit)}>
<TextField {...field.input}
type="text"
label="FIELD"
floatingLabelText="FIELD"
errorText={field.touched ? field.error : null}
/>
<div className="col-xs-12">
<FlatButton
label="ACTIVATE"
fullWidth={true}
style={styles.fullButton}
backgroundColor="#4FCDCC"
hoverColor="#59e5e3"
type="submit"
disabled={submitting}
/>
</div>
</form>
);
}
}
Notice that you forgot return in render method

Resources