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}/>
)
}
Related
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.
I'm a newbie at React, please correct me if I'm wrong...I've used the Switch tag to enclose multiple Routes in my MainComponent.js file. However, I still got an error that says "A may have only one child element". I'm trying to navigate from one page to another.
For example, when I click on Menu in the landing page, I would like to get routed to Menu.
Please advise what went wrong. Thanks in advance.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'font-awesome/css/font-awesome.css';
import 'bootstrap-social/bootstrap-social.css';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
App.js
import React, { Component } from 'react';
import Main from './components/MainComponent';
import './App.css';
import { BrowserRouter } from 'react-router-dom';
class App extends Component {
// pass dishes to children (MenuComponent.js) as props
/*
constructor(props) {
super(props);
this.state = {
dishes: DISHES
};
}*/
render() {
return (
<BrowserRouter> {/* Make use of React Router */}
<div className="App">
<Main />
</div>
</BrowserRouter>
);
}
}
export default App;
MainComponent.js
// Container Component
import React, { Component } from 'react';
import Menu from './MenuComponent';
import DishDetail from './DishdetailComponent';
import Header from './HeaderComponent';
import Footer from './FooterComponent';
import Home from './HomeComponent';
import { DISHES } from '../shared/dishes'; // .. means to go up one level to src
import { Switch, Route, Redirect } from 'react-router-dom';
class Main extends Component {
// pass dishes to children (MenuComponent.js) as props
constructor(props) {
super(props);
this.state = {
dishes: DISHES,
// selectedDish: null
};
}
/*
onDishSelect(dishId) {
this.setState({selectedDish: dishId});
}
*/
render() {
const HomePage = () => {
return (
<Home />
);
}
return (
<div>
<Header />
<Switch>
<Route path="/home" component={HomePage} />
<Route exact path="/menu" component={() => <Menu dishes={this.state.dishes} />} /> {/* path should exactly match /menu and nothing else after /menu */}
{/* component={() => <Menu dishes={this.state.dishes} />} ----> this will allow to pass props to Menu component */}
<Redirect to="/home" /> {/* if the path doesn't match any above, redirect to /home */}
</Switch>
<Footer />
</div>
);
}
}
export default Main;
Just remove the <div className="App"> from your App.js file.
And use the below code as I have written below. It will 100% work for you.
import { BrowserRouter } from 'react-router-dom';
class App extends Component
{
render() {
return (
<BrowserRouter>
<Main/>
</BrowserRouter>
);
}
}
export default App;
I am trying to learn HOC in reactjs and trying to understand this basic example..
I have 3 files named First.js, Second.js and App.js. Now how I need to define those files so that computation done in first file should be accessible to second file.
App.js
import React, { Component } from 'react';
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom';
import First from './First';
import Second from './Second';
class App extends Component {
render() {
return (
<Router>
<Switch>
<Route exact path='/' component={First}/>
<Route exact path='/Second' component={Second}/>
</Switch>
</Router>
);
}
}
export default App;
First.js
import React, {Component} from 'react';
import {Link} from 'react-router-dom';
import Second from './Second';
class First extends Component{
constructor(props){
super(props);
this.state={
number : 1,
};
}
increment = event => {
this.setState({
number : this.state.number + 1
});
}
decrement = event => {
this.setState({
number : this.state.number - 1
});
}
render(){
return(
<div>
{this.state.number}
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
<Second number={this.state.number}/>
<Link to='/Second'>Second</Link>
</div>
);
}
}
export default First;
Second.js
import React, {Component} from 'react';
class Second extends Component{
render(){
return(
<div>
{this.props.number}
</div>
);
}
}
export default Second;
I want to access First.js variable in second.js. Give me solution.
Thanks in advance.
Try this
<Route path="/Second" render={()=> (
<div>
100
</div>
)}/>
The above implementation that you have shown isn't of an HOC, rather a simple Route implementation, Since you are rendering the Second component inside of First you would want to render the /second route inside first
import React, { Component } from 'react';
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom';
import First from './First';
import Second from './Second';
class App extends Component {
render() {
return (
<Router>
<Switch>
<Route path='/' component={First}/>
</Switch>
</Router>
);
}
}
export default App;
First.js
import React, {Component} from 'react';
import {Link} from 'react-router-dom';
import Second from './Second';
class First extends Component{
constructor(props){
super(props);
this.state={
number : 1,
};
}
increment = event => {
this.setState({
number : this.state.number + 1
});
}
decrement = event => {
this.setState({
number : this.state.number - 1
});
}
render(){
return(
<div>
{this.state.number}
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
<Route path="/Second" render={(props)=> <Second number={this.state.number} {...props}/>} />
<Link to='/Second'>Second</Link>
</div>
);
}
}
export default First;
I am working on a React.js web app , for some reasons I am not able to pass url parameters.
An example is being shown below:
Routes:
import React from "react";
import {BrowserRouter, Route, Switch, Redirect} from 'react-router-dom';
import Helloworld from './components/helloworld/helloworld.component';
import SecondView from './components/secondview/secondview.component';
import ThirdView from "./components/thirdview/thirdview.component";
const AppRoutes = () => (
<BrowserRouter>
<Switch>
<Route exact path='/' component={Helloworld}/>
<Route path='/secondview' component={SecondView}/>
<Route path='/thirdview' component={ThirdView}/>
<Route path='/thirdview/:number' component={ThirdView}/>
<Redirect from='*' to='/' />
</Switch>
</BrowserRouter>
);
export default AppRoutes;
Secondview Component
import React from 'react';
import {Link, withRouter} from 'react-router-dom';
class SecondView extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.log("I am being called SecondView component...");
}
render() {
return (
<div className={"boxDiv"}>
<p>Second View</p>
<Link to={{pathname: '/thirdview/7'}}> GO to third view with parameter value. </Link>
</div>
);
}
}
export default withRouter(SecondView);
Thirdview comopnent:
import React from 'react';
import { Route, Link,withRouter } from 'react-router-dom';
import FourthView from "../fourthview/fourthview.component";
class ThirdView extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
}
render() {
console.log(this.props.match.params);
return (
<div className={"boxDiv"}>
<p>Third View</p>
{ console.log(this.props)}
<h1>parameter passed: (#{this.props.params.number})</h1>
</div>
);
}
}
export default withRouter(ThirdView);
What I want, is to be able to get /:number value on my thirdview component! Anyone knows how to achieve such thing in React.js? Are there other ways doing this?
What I get is empty object!
I think it should be:
{this.props.match.params.number}
instead of
{this.props.params.number}
and you don't need withRouter on ThirdView and SecondView as are passed to Route already.
EDIT:
Since you want to render the same component for /thirdview and /thirdview/7 use optional param matcher
<Switch>
<Route exact path='/' component={Helloworld}/>
<Route path='/secondview' component={SecondView}/>
<Route path='/thirdview/:number?' component={ThirdView}/>
<Redirect from='*' to='/' />
</Switch>
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.