How to always execute app.js code before any routes - javascript

I am working on a simple application with routes.
I have defined 2 routes as below:
App.js
import React from 'react';
import { Route, Routes, BrowserRouter } from 'react-router-dom';
import './App.css';
import Route1 from './components/Route1';
import Route2 from './components/Route2';
class App extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.log('This is from App.js')
}
render() {
<BrowserRouter>
<Routes>
<Route path="/route1" element={[<Route1]}/>
<Route path="/route2" element={[<Route2]}/>
</Routes>
</BrowserRouter>
}
}
export default App;
Route 1
import React, { Component, createRef } from 'react'
class Route1 extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
Console.log("This is from Route1")
// some code
}
render() {
return()
}
export default Route1
Route 2
import React, { Component, createRef } from 'react'
class Route2 extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
Console.log("This is from Route2")
// some code
}
render() {
return()
}
export default Route1
I want to execute code written in app.js first, even before routes.
When I am on localhost:3000/route1, I can console output as below:
This is from Route1
This is from App.js
But I want to execute the app.js code before any routes, so expected putout is:
This is from App.js
This is from Route1

Writing your code in constructor will do your job. It should look like this :
constructor(props) {
super(props);
console.log('This is from App.js')
}

The App component needs to completely mount/render its sub-ReactTree prior to itself being considered mounted/rendered. If there is some logic you want to run prior to children being rendered then you might need to add some "initial render" state to the parent and conditionally render the children once the parent component has mounted and completed the logic.
Example:
class App extends React.Component {
state = {
loaded: false,
}
componentDidMount() {
console.log('This is from App.js');
this.setState({ loaded: true });
}
render() {
const { loaded } = this.state;
return (
<BrowserRouter>
{loaded && (
<Routes>
<Route path="/route1" element={<Route1 />} />
<Route path="/route2" element={<Route2 />} />
</Routes>
)}
</BrowserRouter>
);
}
}

Related

How to navigate to homepage upon form submit in react web using react-router-dom v6.2.1?

I have a Smart component class page PhoneDirectory.js, where I have used BrowserRouter and Route to route to the ShowSubscribers page("/") and AddSubscribers page ("/add"). My requirement is to redirect to the ShowSubscribers page("/") upon form submission on the AddSubscribers page but not understand how to implement that. I tried using this.props.history.push("/") but it isn't working. I am new to React, can anyone please help?
import React from 'react';
import AddSubscriber from './AddSubscriber';
import ShowSubscribers from './ShowSubscribers';
import {BrowserRouter , Route, Routes} from 'react-router-dom';
export default class PhoneDirectory extends React.Component{
constructor(){
super();
this.state = {[]};
}
addSubscribers = (subscribers) =>{...}
deleteSubscribers = (subscriberId) =>{...}
render() {
return (
<BrowserRouter>
<Routes>
<Route exact path='/' element={<ShowSubscribers deleteSubscribers={this.deleteSubscribers} subscribersList={this.state.subscribersList}/>}/>
<Route exact path='/add' element={<AddSubscriber addSubscribers={this.addSubscribers}/>}/>
</Routes>
</BrowserRouter>
)
}
}
Dumb component AddSubscriber page
import React from 'react';
import Header from './Header';
import './AddSubscriber.css';
import {Link} from "react-router-dom";
export default class AddSubscriber extends React.Component {
constructor() {
super();
this.state = {
id: 0,
name:'',
phone:''
}
}
onChangeHandler = (event) =>{...}
onFormSubmitted = (event) =>{
event.preventDefault();
this.props.addSubscribers(this.state);
this.setState({id:0, name:"", phone:''});
// Need logic to redirect to "/" i.e., ShowSubscribers page
}
render() {
return (<div>
<Header heading="Add Subscriber"/>
<div className="component-body-container">
<Link to="/">
<button className="custom-btn">Back</button>
</Link>
<form className="subscriber-form" onSubmit={this.onFormSubmitted.bind(this)}>
...............
<button type="submit" className="custom-btn add-btn">Add</button>
</div>
</form>
</div>
</div>)}
}
I tried this.props.history.push("/"), but it didn't worked.
react-router-dom v6 support only hooks version i suggest since you use class component to downgrade the version of react-router-dom in package.json.
"dependencies": {
...
"react-router-dom": "5.2.1",
},
Now you need to run : npm install or yarn install
Your Route component will look like that
import React from 'react';
import AddSubscriber from './AddSubscriber';
import ShowSubscribers from './ShowSubscribers';
import { Route, Switch, BrowserRouter as Router } from 'react-router-dom';
export default class PhoneDirectory extends React.Component{
constructor(){
super();
this.state = {[]};
}
addSubscribers = (subscribers) =>{...}
deleteSubscribers = (subscriberId) =>{...}
render() {
return (
<Router>
<Switch>
<Route exact path='/'>
<ShowSubscribers {...your props goes here}/>
</Route>
<Route exact path='/add'>
<AddSubscriber {...your props goes here}/>
</Route>
</Switch>
</Router>
)
}
}
Now you are able to call this.props.history.push
import React from 'react';
import Header from './Header';
import './AddSubscriber.css';
export default class AddSubscriber extends React.Component {
constructor() {
super();
this.state = {
id: 0,
name:'',
phone:''
}
}
onChangeHandler = (event) =>{...}
onFormSubmitted = (event) =>{
event.preventDefault();
this.props.addSubscribers(this.state);
this.setState({id:0, name:"", phone:''});
// Need logic to redirect to "/" i.e., ShowSubscribers page
}
render() {
return (<div>
<Header heading="Add Subscriber"/>
<div className="component-body-container">
<button className="custom-btn" onClick={()=>this.props.history.push('/')} >Back</button>
<form className="subscriber-form" onSubmit={this.onFormSubmitted.bind(this)}>
...............
<button type="submit" className="custom-btn add-btn">Add</button>
</div>
</form>
</div>
</div>)}
}
I think that you need to wrap your AddSubscriber page with withRouter HOC
class AddSubscriber extends React.Component{
...some-code....
}
export default withRouter(AddSubscriber)
you need navigation logic (this.props.history.push("/"))
to be located a addScubscribers page.
(you have it at "homepage" instead)

React Router returns blank page with correct pathing

I'm new to react. I'm following a tutorial, and my code is exactly the same as the tutorial, but the result isn't. Basically, my page routes are returning a blank page. There's no error in the console, so I'm not sure what I'm doing wrong. Here's my code
Homepage.js
import React, { Component } from "react";
import Login from "./Login";
import CreateUser from "./CreateUser";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
Redirect,
} from "react-router-dom";
export default class HomePage extends Component {
constructor(props) {
super(props);
}
render() {
return (
<Router>
<Switch>
<Route exact path="/">
<p>This is the homepage</p>
</Route>
<Route path="/login" component={Login} />
<Route path="/createuser" component={CreateUser} />
</Switch>
</Router>
);
}
}
Login.js Component
import React, { Component } from "react";
export default class Login extends Component {
constructor(props) {
super(props);
}
render() {
return <p>This is the Login Page</p>;
}
}
CreateUser.js Component
import React, { Component } from "react";
export default class CreateUser extends Component {
constructor(props) {
super(props);
}
render() {
return <p>This is the Create User Page</p>;
}
}
App.js
import React, { Component } from "React";
import { render } from "react-dom";
import HomePage from "./HomePage";
export default class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<HomePage />
</div>
);
}
}
const appDiv = document.getElementById("app"); // get 'app' div
render(<App />, appDiv); // place App component into app div
I've tried changing the import "react" code in line 1 to import 'react' among other things.
Any ideas? Thanks!
Try changing the paths to "/login" and "/createuser" in Homepage.js
I am using Django on the backend of the React project I'm working on. The routes were not connected to the url.py file for the url configuration for my Django app.

Unable to console.log props using Link

I am trying to make a single web application. Basically, I am trying to use the ReactRouter to display what is passed as a Route Parameter. However, I am unable to do that. To check if somethings wrong, I decided to console.log out this.props.match, still nothing shows up. Could someone explain what the problem is? And a possible get around?
My code is-
import React from 'react';
export default class Post extends React.Component {
state = {
id: null
}
componentDidMount(props) {
console.log(this.props.match);
}
render = () => {
return (<div>Hello WOrld</div>)
}
}
The App.js file:
import React, { Fragment, Component } from 'react';
import Navbar from './components/Navbar';
import Home from './components/Home';
import Contact from './components/Contact';
import About from './components/About'
import Post from './components/Post';
import { BrowserRouter, Route } from 'react-router-dom';
class App extends Component {
render = () => {
return (
<BrowserRouter>
<div className="App">
<Navbar />
<Route exact path="/" component={Home} />
<Route path="/contact" component={Contact} />
<Route path="/about" component={About} />
<Route path="/:post-id" component = {Post} />
</div>
</BrowserRouter>
);
}
}
export default App;
I just ran your code on my end, it looks like the problem is using /:post-id. I changed that to /:pid and it worked. I got the below object when I console log this.props.match
{
"path":"/:pid",
"url":"/1",
"isExact":true,
"params":
{
"pid":"1"
}
}
I hope this helps.
You have to load the component with router
try this
import { withRouter } from 'react-router-dom';
class Post extends React.Component {
state = {
id: null
}
componentDidMount(props) {
console.log(this.props.match);
}
render = () => {
return (<div>Hello WOrld</div>)
}
}
export default withRouter(Post);

component props returns empty react js

I have created two components App and leftBar. I'm getting the Class component props in App component. But the same prop is empty in LeftBar.
Index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
/** Component **/
import App from './App';
ReactDOM.render(
<BrowserRouter>
<Switch>
<Route path="/:folders/:actions" component={App}></Route>
</Switch>
</BrowserRouter>, document.getElementById('app'));
App.js
import React, {Component} from 'react';
import {BrowserRouter as Router, Route} from 'react-router-dom';
import LeftBar from './components/left-bar';
class App extends Component {
constructor(props){
super(props);
console.log(this.props); //Returns the object
}
render(){
return (
<LeftBar />
)
}
}
LeftBar.js
class LeftBar extends Component{
constructor(props) {
super(props);
this.state = {
leftBar: ["sarath"]
}
console.log(this.props); //this returns empty object {}
}
}
someone point out what was the issue behind this. I want to use props across the multiple components.
react-router will not pass props down the way you are hoping. You need to first pass props to App by doing
// ...
<Route path="/:folders/:actions" component={props => <App {...this.props} />} />
Then you need to pass them along in your child component(s). I am including this.state with the assumption you want to use this inside of LeftBar but you may remove {...this.state} if that is incorrect:
// ...
render () {
return (
<LeftBar
{...this.props}
{...this.state} />
)
}
Because you don't assign any props on <LeftBar />.
You have to pass the required props to this component as well:
render(){
return (
<LeftBar {...this.props}/>
)
}

React - Get data before rendering pages

I have a situation where I need to fetch updated props within componentWillMount()
My Layout :
#connect((store) => {
//console.log(store);
return {
element: store.elements.elements,
connections: store.connections.connections,
attributes: store.attributes.attributes,
media: store.media.media,
places: store.places.places,
user: store.user.user
};
})
export default class Layout extends React.Component {
componentWillMount() {
this.props.dispatch(fetchUser())
}
componentWillReceiveProps(nextProps) {
this.props.dispatch(updateStoreUser(nextProps.user))
}
shouldComponentUpdate(nextProps) {
console.log(nextProps);
return true;
}
render() {
const { location } = this.props;
return (
<div className="main-container">
<Header/>
<NavConnector/>
{this.props.children}
</div>
);
}
}
{this.props.children} will render pages depending on the route.
I have a BasicInfo Component :
componentWillMount() {
console.log(this.props);
this.props.dispatch(fetchPlaces(1))
}
Where I need to pass user id to fetchPlaces, something like this this.props.dispatch(fetchPlaces(this.props.user.id)
But this.props does not have user.id yet, in the componentWillReceiveProps of the layout I'm updating the store, but gets updated after componentWillMount() of BasicInfo component is called.
The console log :
UPDATE
I have a connector for BasicInfo, this.props.user inside the render method is always undefined. But the store has the user values by now.
Is there any way to pass data from Layout? The place where {this.props.children} is being called? Because that's where the BasicInfoConnector is being called.
import React from "react"
import * as Redux from 'react-redux';
import Basicinfo from "./Basicinfo"
const mapStateToProps = function (store) {
return {
elements: store.elements.elements,
places: store.places.places,
geocode : store.geocode.geocode,
user : store.user.user
};
};
class BasicinfoConnector extends React.Component{
render() {
console.log(this.props.user);
return (
<BasicInfoConnector elements={this.props.elements} places={this.props.places} geocode={this.props.geocode} user={this.props.user}/>
);
}
}
export default Redux.connect(mapStateToProps)(BasicinfoConnector);
Client JS
import React from "react"
import ReactDOM from "react-dom"
import { Router, Route, IndexRoute, hashHistory } from "react-router"
import { Provider } from "react-redux"
import { useScrollToTop } from "scroll-behavior"
import store from "./store"
import '../styles/sass/master/global.scss'
import Layout from "./components/Layout";
import Alerts from "./components/Dashboard/Alerts/Alerts"
import AttributesConnector from "./components/Dashboard/Attributes/AttributesConnector"
import BasicInfoConnector from "./components/Dashboard/Basicinfo/BasicinfoConnector"
import ConnectionsConnector from "./components/Dashboard/Connections/ConnectionsConnector"
import MediaConnector from "./components/Dashboard/Media/MediaConnector"
import Stats from "./components/Dashboard/Stats/Stats"
const app = document.getElementById('app')
ReactDOM.render(
<Provider store={store}>
<Router histroy={hashHistory} onUpdate={() => window.scrollTo(0, 0)}>
<Route path="/" component={Layout}>
<IndexRoute component={BasicInfoConnector}></IndexRoute>
<Route path="location" component={BasicInfoConnector}></Route>
<Route path="alerts" component={Alerts}></Route>
<Route path="attributes" component={AttributesConnector}></Route>
<Route path="connections" component={ConnectionsConnector}></Route>
<Route path="media" component={MediaConnector}></Route>
<Route path="stats" component={Stats}></Route>
</Route>
</Router>
</Provider>,
app);
Assuming that you want to fetch places in componentWillMount, the only solution is to not render the component at all using conditional rendering until the user id is available since componentWillMount gets called only once. Something like this:
{this.props.user?<BasicInfo />:null}
Update:
You need to export a component which is connected (subscribed) to redux store. You are exporting the component which is not connected yet. Just remove the export default before the component declaration
class BasicinfoConnector extends React.Component
and add an export default before the connect statement.
export default Redux.connect(mapStateToProps)(BasicinfoConnector);
This should fix your issue.

Categories

Resources