I am trying to get my react component to render in Meteor. I don't see any error messages or anything in the console, however, the component doesn't seem to display.
I am using react-router. I added log statements and it appears that the renderRoutes() function does get called, also, I see errors in the console when I change the directories for my imports (I get an error if I change the first import statement to import {Home} from '../home/blah'). I am not really sure what to try next.
Here is my router, which is in client/imports/lib/router.js.
import React from 'react';
import { Router, Route, Switch } from 'react-router';
import {createBrowserHistory} from 'history';
import {Home} from '../home/home';
import {Login} from '../login/login';
import {Connect} from '../connect/connect';
const browserHistory = createBrowserHistory();
export const renderRoutes = () => (
<Router history={browserHistory}>
<Switch>
<Route exact path="/" component={Home}/>
<Route exact path="/login" component={Login}/>
<Route exact path="/connect" component={Connect}/>
</Switch>
</Router>
);
Here is my home page. The other pages have a similar structure. The home page is in client/imports/home/home.js.
import React, { Component } from 'react';
export default class Home extends Component {
constructor(){
super()
this.state = {
}
}
render() {
return (
<div><h1>hello from the home page</h1></div>
);
}
}
Finally, this is my main.js. It's in client/main.js.
import { Meteor } from 'meteor/meteor';
import { render } from 'react-dom';
import { renderRoutes } from './imports/lib/router.js';
import './main.html';
Meteor.startup(() => {
render(renderRoutes(), document.getElementById('app'));
});
Again, I don't see any error messages. The home page just doesn't render. I put console.log's in the constructor for the Home component and I do not see anything. I'm not sure if there is something about React that I am not understanding or if I need to change the way I am using the router.
Please let me know what I should try next, and if there is any more information I should include.
Thanks!
If you're exporting component using export default
export default class Home extends Component {
then you should import it this way:
import Home from '../home/home';
Read more about named and default exports
For the future - back to the source, check original code (from docs) first (usually working) - it's not hard to see the difference ;)
Related
I'm writing my first react application and I wanna use a Switch to show the component corresponding to the route. One of the routes uses a param. The problem is that the match attribute is missing from props so route matching doesn't seem to work (No component is inserted).
When I try to console.log this.props.match it returns undefined.
import { Switch, Route } from 'react-router-dom';
import React, { Component } from 'react';
import Index from './Index';
import Debate from './Debate';
class App extends Component {
componentDidMount() {
console.log(this.props.match); // I get undefined
}
render() {
return (
<div className="App">
<Switch>
<Route path="/debats" component={Index} />
<Route path="/debat/:debateSlug" component={Debate} />
</Switch>
</div>
);
}
}
export default withConfig(App);
I want to be able to access the match attribute so that the correct component is displayed.
Add to this in your Component
import {withRouter} from 'react-router-dom';
export default withRouter(withConfig(App));
I'm trying to add routes to my react project. I have three separate components:
Window.js
import React, { Component } from 'react';
import SideBar from "../SideBar/SideBar";
import MainBody from "../MainBody/MainBody";
import { BrowserRouter as Router} from "react-router-dom";
class Window extends Component{
render() {
return (
<div>
<Router>
<SideBar />
<MainBody />
</Router>
</div>
);
}
}
export default Window
SideBar.js
import React, { Component } from 'react';
import PropTypes from "prop-types";
import { BrowserRouter as Link} from "react-router-dom";
class SideBar extends Component {
render() {
return(
<Link to="/">Home</Link>
<Link to="/about">About</Link>
);
}
}
export default SideBar;
MainBody.js
import React, { Component } from 'react';
import Home from "./Home/Home";
import About from "./About/About";
import { BrowserRouter as Route} from "react-router-dom";
class MainBody extends component {
render() {
return(
<div>
<Route exact path="/" component={Home}>
<Route path="/about" component={About}>
</div>
);
}
}
export default MainBody;
So basically, when I click one of my links in SideBar, I want to transition to that link in my Main Body (the Home and About just display their titles). However, When I run this, my Window, MainBody, and SideBar components work but my Home and About components do not get displayed. I've properly imported the router components into each component file. If I place the Routes from MainBody into the Window component, they get displayed (Not sure if the router links work with it though). Any suggestions would be helpful!
There are few typos in that snippets, dunno ifit was made when rewriting or u have it in your codebase, but be careful about them (component instead of Component, wrongly writtern render function with multiple elements returned etc).
import { BrowserRouter as Link} from "react-router-dom";
Theese imports are also wrong, You have to import Link not something as Link. You are only renaming import BrowserRouter to Link.
import { Link } from "react-router-dom";
And same for Route.
Here is example codesanbox . Let me know if that is what you wanted.
I have upgraded to React Router V4 and now struggling with the history.push method.
I have an index.js file:
import React from "react";
import { render } from "react-dom";
import { BrowserRouter, Route } from 'react-router-dom';
import createBrowserHistory from 'history/createBrowserHistory';
const history = createBrowserHistory();
import { Main} from "./components/Main";
import { About } from "./components/About";
import { Cars} from "./components/Cars";
class App extends React.Component {
render() {
return (
<BrowserRouter history={history}>
<div>
<Route path={"/"} component={Main} />
<Route path={"/cars"} component={Cars}/>
<Route path={"/about"} component={About}/>
</div>
</BrowserRouter>
)
}
}
render(<App/>, window.document.getElementById("app"));
And then I have another file, where I added a simple to return to a certain page which looks like this:
import React from "react";
import createBrowserHistory from 'history/createBrowserHistory';
const history = createBrowserHistory();
export class Cars extends React.Component {
navigateBack() {
history.push('/')
}
render() {
return(
<div>
<h3>Overview of Cars</h3>
<p>Model: </p>
<button onClick={this.navigateBack} className="btn btn-primary">Back</button>
</div>
)
}
}
So, I cannot figure out whats going wrong here. When I click on the button, the URL changes to / but thats all. Is there someone who can help me out?
EDIT
I found out, that it works when I do this:
this.props.history.push('/home')
and
<button onClick={this.onNavigateHome.bind(this)}
but it seems wrong somehow??
when I do
this.context.history.push('/home')
I get Cannot read property 'context' of null but why?? Is my <BrowserRouter> setup wrong??
Anyway, thanks for the help :)
You have to import {withRouter} from 'react-router-dom' and export your class in this way
export default withRouter(Cars)
Try adding forceRefresh={true} to your BrowserRouter.
<BrowserRouter forceRefresh={true}>
With v4 you have to use this.context.history.push('/cart');
check out these posts for more insights:
How to push to History in React Router v4?
history.push not working when using BrowserRouter
Try to use history from props and ensure that your export is wrapped with withRouter.
Ex:
this.props.history.push('/test')
export default withRouter(TestComponent)
I am working in a react application using redux, react-router and react-router-redux. So it is a simple App and in this application I need use a simple, route view. I have read the documentation and can made mi route without problems, but at moment of added a Template at routes I had problems. I need pass the dispatched and State of the reducers to the views and the Template for can manipulate spinners and other elements in the Template. I don't sure the how make it or if I am making correctly.
Could you help me, please?
This is my router code:
import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux';
import {Route} from 'react-router';
import {ConnectedRouter} from 'react-router-redux';
import {Switch} from 'react-router-dom';
import {store, history} from './store/index';
import Layout from './components/Layout';
import './bootstrap-3/css/bootstrap.min.css';
/* Components */
import Home from './components/abouts/home';
import About from './components/abouts/about';
import NoMatch from './components/abouts/nomatch';
import Artists from './components/artists';
const NodeId = document.getElementById('root');
ReactDOM.render(
<Provider store={store}>
<ConnectedRouter history={history}>
<Layout>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/artists" component={Artists}/>
<Route component={NoMatch}/>
</Switch>
</Layout>
</ConnectedRouter>
</Provider>, NodeId);
So I don't sure of how pass the redux State and the dispatched to component of route, So I am doing something like that in each component, I thing that there is one better form of do it.
import {connect} from 'react-redux';
import * as artistActions from './actions/artistActions';
import * as globalConfigActions from './actions/globalConfigActions';
class Abouts extends Component {
render() {
console.log('Abouts Component: ', this);
return (
<div>
<h1>About</h1>
</div>
);
}
}
const mapStaeToProps = (state) => {
return {
artist: state.artist,
globalConfig: state.globalConfig
}
};
const mapDispatchToProps = (dispatch) => {
return {
fetchArtist: () => {
return dispatch(artistActions.fetchArtist());
},
globalConfigActions: {
showSpinner: () => {
dispatch(globalConfigActions.showSpinner());
},
hiddenSpinner: () => {
dispatch(globalConfigActions.hiddenSpinner());
}
}
}
};
export default connect (mapStaeToProps, mapDispatchToProps)(About);
Of that form I can pass the State and the dispatched to component to each main component but I need pass the State and the dispatched to the Template, when I have tried do it with the template the routes doesn't work and the view doesn't change.
If I use one simple template without the "mapDispatchToProps" and "mapStaeToProps" of redux it works perfect but the layout doesn't have access to methods or state of redux.
Someone could say me how I can make it correctly, please?
Thank you very much
I'm working on a simple web app with Horizon and React to learn more about web design.
For some reason, my Router will not Route to various sub directories. For instance, I get my Layout page when I visit localhost:8181/, but when I visit localhost:8181/Home, I get (displayed in the webpage in Firefox) 'File "dist\Home" not found."
I also get this code in the Firefox console:
The character encoding of the plain text document was not declared.
The document will render with garbled text in some browser
configurations if the document contains characters from outside the
US-ASCII range. The character encoding of the file needs to be
declared in the transfer protocol or file needs to use a byte order
mark as an encoding signature.
Here is my Router Code:
//Routing.jsx
import React from 'react'
import { Router, Route, Link, browserHistory, IndexRoute, IndexRedirect } from 'react-router'
//Routes:
import MainLayout from './components/MainLayout.jsx'
import Search from './components/Search.jsx'
import PickFilm from './components/PickFilm.jsx'
import Login from './components/Login.jsx'
import Home from './components/Home.jsx'
export const Routing = () => {
return (
<Router history={browserHistory}>
<Route path = "/" component = {MainLayout} >
<Route path = "/Home" component = {Home} />
<Route path = "/Search" component = {Search} />
<Route path = "/PickFilm" component = {PickFilm} />
</Route>
<Route path = "/Login" component = {Login} />
</Router>
)
}
Here is my Index code:
//Index.jsx
import React from 'react'
import ReactDOM from 'react-dom'
import { Routing } from './Routing.jsx'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
// Routing Information
ReactDOM.render((
<MuiThemeProvider>
<Routing />
</MuiThemeProvider>
), document.getElementById('root'));
Here is my component for Home:
//components/Home.jsx
import React, { Component } from 'react'
export default class Home extends Component {
render() {
return (
<span>You're home.</span>
)
}
}
Here is my component for the Layout:
//components/MainLayout.jsx
import React, { Component } from 'react'
import Navbar from './Navbar.jsx'
//Needed for onTouchTap
//http://stackoverflow.com/a/34015469/988941
import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();
export default class MainLayout extends Component {
render() {
return(
<div>
<Navbar />
</div>
);
}
}
Like I said, the layout will render when visiting localhost:8181/. But I get that error when visiting any of the subcomponents, such as localhost:8181/Home. Where am I going wrong?
I'm using these software versions:
babel-core: 6.10.4 (+ plugins and presets for react & es2015),
webpack 1.13.1,
Horizon 1.1.3,
material-ui 0.15.2,
React 15.2.1,
React-router 2.5.2.
You forgot to include {this.props.children} inside the render method of MainLayout so your child routes aren't being rendered at all.