React Link not automatically updating page content? - html

While clicking on the links updates the slug, I have to manually refresh the page in order to get the page content to update.
app.js:
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import NavigationContainer from './titlebar';
import AllLinks from './all-links';
import Home from './home';
export default class App extends Component {
render() {
return (
<div className='app'>
<NavigationContainer />
<Router>
<Switch>
<Route path="/all-links" component={AllLinks} />
<Route exact path="/" component={Home} />
</Switch>
</Router>
</div>
);
}
}
titlebar.js:
import React, { Component } from "react";
import { NavLink } from "react-router-dom";
export default class NavigationContainer extends Component {
render() {
return (
<div className="navigation-container">
<div className="text-wrapper">
<div className="nav-left">
<NavLink exact to="/">
Redis Link Shortener
</NavLink>
</div>
<div className="nav-right">
<NavLink to="/all-links" >
All Links
</NavLink>
</div>
</div>
</div>
)
}
}
I've tried going through documentation, going through similar questions, and going through code I've written in the past that does work in this regard. As far as I can tell, what I'm using is identical to code I've written in the past that has worked. I'm completely stuck for why it isn't automatically rendering.

Related

React-router-dom: Very simple nested routing does not work

I have searched through different tutorials and multiple stackOverflow questions. And none of which, helped me solve a very basic problem:
Implement nested routes with react-router-dom
Here's my code so far:
App.js
<Route exact path="/home" name="Home" component={DefaultLayout} />
DefaultLayout.js
<Route path="/home/users" component={Users} />
When I go to /home/users, I get a blank screen because react-router-dom is looking-up the definition of that route inside App.js instead of searching it inside DefaultLayout.js..
So I have two questions:
QUESION 1: What am I doing wrong exactly?
QUESTION 2: How does react-router-dom know that it should look for the nested route inside DefaultLayout.js instead of inside App.js?
It has been two days and I still cannot solve this simple problem.
Any help is very much appreciated.
EDIT 1: I have started a new project just for the sake of implementing a very simple nested routing:
App.js
import React from "react";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import ParentComponent from "./nestedComponents/ParentComponent";
function App() {
return (
<div>
<BrowserRouter>
<Switch>
<Route exact path="/home" name="Home" component={ParentComponent} />
</Switch>
</BrowserRouter>
</div>
);
}
export default App;
ParentComponent.js
import React from "react";
import nestedComponentOne from "./nestedComponentOne";
import nestedComponentTwo from "./nestedComponentTwo";
import { Switch, Route } from "react-router-dom";
export default function ParentComponent() {
return (
<div>
PARENT COMPONENT
<Switch>
<Route path="home/nestedComponentOne" component={nestedComponentOne} />
<Route path="home/nestedComponentTwo" component={nestedComponentTwo} />
</Switch>
</div>
);
}
nestedComponentOne.js
import React from "react";
export default function nestedComponentOne() {
return <div>NESTED COMPONENT 1</div>;
}
nestedComponentTwo.js
import React from "react";
export default function nestedComponentTwo() {
return <div>NESTED COMPONENT 2</div>;
}
But, I still get a blank screen whenever I try to access a nested component...
You have this problem:
React-router urls don't work when refreshing or writing manually
The simplest fix is to replace the BrowserRouter with a HashRouter

React Router Bootstrap and Navbar redirection

I read so much today and yesterday and I am totally stuck in my development. In order to learn React.Js, I am making a simple website that displays pictures and description by categories. The problem I am facing is the link between my NavItems (of the navbar) and the redirections.
I have this router in my index.js:
render((
<Router history={hashHistory}>
<Route path="/" component={App}>
<IndexRedirect to="/index" />
<Route path="/index" component={Home}/>
<Route path="/dogs" component={Dogs}/>
<Route path="/cats" component={Cats}/>
</Route>
</Router>
), document.getElementById('app'))
Navbar.js:
import React from 'react'
import {
Navbar as BoostrapNavBar,
Nav,
NavItem,
MenuItem,
NavDropdown,
Jumbotron,
Button } from 'react-bootstrap';
import { LinkContainer } from 'react-router-bootstrap';
export default class Navbar extends React.Component {
render () {
return (
<BoostrapNavBar inverse collapseOnSelect>
<BoostrapNavBar.Header>
<BoostrapNavBar.Brand>
{this.props.navbar_title}
</BoostrapNavBar.Brand>
<BoostrapNavBar.Toggle />
</BoostrapNavBar.Header>
<BoostrapNavBar.Collapse>
<Nav pullRight>
<NavItem href="/dogs">Dogs</NavItem>
<NavItem href="/cats">Cats</NavItem>
</Nav>
</BoostrapNavBar.Collapse>
</BoostrapNavBar>
);
}
}
So my site render but, if I click one of my navitems, then a message will appear: Cannot GET /dogs.
So, I began to search on the internet about how does navbar works with react-router and... I got so many answers, but I can't make it work, I don't get why. I tried LinkContainer but something is wrong with history, so I check my Router in index.js without any success.
I read some articles about <Switch>, <Browser>, etc, but same, no success :( any idea?
Thanks for any help
Could you do something like this?
import { Link } from 'react-router-dom';
import { NavBar, Nav, NavItem} from 'react-bootstrap';
...
<Nav>
<NavItem componentClass={Link} href="/dogs" to="/dogs" active={location.pathname === '/dogs'}>Dogs</NavItem>
<NavItem componentClass={Link} href="/cats" to="/cats" active={location.pathname === '/cats'}>Cats</NavItem>
</Nav>
Gotten from here

Reducer is getting called thrice for each routing without performing any action

I am trying to integrate redux with react-routing. I found a situation like,
i am accessing the same reducer by two component. i am updating the sate from one component, state is getting updated in store. while routing to the another component,again reducer is getting called automatically and intialized the state with default value.
Here what is happening as per my understanding,reducer is getting called from store and passing the state value as null, so it is taking the default value (feature of ES6) and in same way action.type would null only.
So, My question is why reducer is getting called for every routing even though there is no any user actioned performed. even though if it is calling the reducer, why store is passing null value to the state argument of reducer instead of the state updated by component before routing.
Reducer:
export const userReducer=function(state={name:"rohit",id:123},action){
console.log("user reducer called",state);
switch(action.type){
case "NEW_USER_REG":
console.log("user added");
state=Object.assign({},action.payload);
break;
case "DELETE_USER":
consol.log("user deleted");
break;
}
return state;
}
Component 1(reading and writing from store state):
import React from 'react';
import {Navbar} from '../component/navbar';
import {connect} from 'react-redux'
class Main extends React.Component{
render(){
return(
<div>
<h1>This is main comp.. below is state got from store</h1>
<input type="text" ref="name"/>
<button onClick={()=>this.props.register("rajesh")}>update state</button>
<hr></hr>
{this.props.user.name}
</div>);
}
}
const stateToprops=(state)=>{
return {
user:state.userReducer
}
}
const dispatchToProps=(dispatch)=>{
return{
register:(name)=>{
console.log("fun called ",name);
dispatch({
type:"NEW_USER_REG",
payload:{name:name,id:1}
})
}
}
}
export default connect(stateToprops,dispatchToProps)(Main);
Component 2(reading from store state):
import React from 'react';
import {connect} from 'react-redux';
export class Second extends React.Component{
render(){
return(
<div>
<h1>Hello, This is active component...</h1>
<hr></hr>
{this.props.user.name}
</div>
)
}
}
const stateToProps=(state)=>{
return{
user:state.userReducer
}
}
const dispatchToProps=(dispatch)=>{
return{
adduser:(expense)=>{
dispatch({type:"NEW_USER_REG",payload:expense})
}
}
}
export default connect(stateToProps,dispatchToProps)(Second);
Router Component :
import React from 'react';
import {
BrowserRouter as Router,
Route, Switch
} from 'react-router-dom';
import {Navbar} from '../component/navbar';
import Second from '../component/second';
import Main from '../component/main';
export class App extends React.Component{
render(){
return(
<div>
<div style={{height:80,backgroundColor:'#e8e3e4'}}></div>
<Navbar/>
<div className="text-align: center; margin: auto; width: 60%; padding: 10px;">
<div style={{height:5}}></div>
<div className="container-fluid">
<div className="row">
<div className="col-md-2"> </div>
<div className="col-md-8"style={{height:'auto',backgroundColor:'#e8e3e4'}}>
<Router>
<Switch>
<Route exact path='/' component={Main} />
<Route path='/contact' component={Second}/>
</Switch>
</Router>
</div>
<div className="col-md-2"></div>
</div>
</div>
</div>
</div>
);
}
}
anchor component using not
import React from 'react';
import {Second} from '../component/second';
export class Navbar extends React.Component{
render(){
let styles={width:10};
return(
<div >
<nav className="navbar navbar-inverse" >
<div className="container-fluid">
<div className="navbar-header">
<a className="navbar-brand" href="/">My Learning Project</a>
</div>
<ul className="nav navbar-nav">
<li className="active">Home</li>
<li className="dropdown"><a className="dropdown-toggle" data-toggle="dropdown" href="#">Service<span className="caret"></span></a>
<ul className="dropdown-menu">
<li>Register</li>
<li>Get-Profile</li>
<li>Update</li>
</ul>
</li>
<li>Contact Us</li>
<li>About</li>
</ul>
</div>
</nav>
</div>
);
}
}
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {
BrowserRouter as Router,
Route, Switch
} from 'react-router-dom';
import {App} from './app'
import {store} from './store.js'
import {Provider} from 'react-redux'
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('content')
);
Could you please post some snippets of your code like the reducer which is getting called twice and the 2nd component particularly the part where you are dispatching the action. That way we can probably help you.
Solution
OP was using anchor tags <a> to navigate to different urls which were making the page to reload and the redux store to get created again. Switching to <Link> solved the issue.

react-router v4 alpha7 +dom6 not pushing context through BrowserRouter

With react-router v4 alpha7 and dom alpha6 (latest versions) i get the following error:
Warning: Failed context type: The context `router` is marked as required in `Link`, but its value is `undefined`.
in Link (created by MainComponent)
in p (created by MainComponent)
in div (created by MainComponent)
in MainComponent (created by Route)
in Route
in div
in Router (created by BrowserRouter)
in BrowserRouter
in ApolloProvider
I have seen similar questions like this, but i followed their advice.
BrowserRouter is a top level component around router components
import React from 'react'
import ReactDOM from 'react-dom'
import ApolloClient, { createNetworkInterface } from 'apollo-client';
import { ApolloProvider } from 'react-apollo';
import MainComponent from './components/main.jsx';
import AboutComponent from './components/about.jsx';
import { BrowserRouter, Route, Link } from 'react-router-dom'
const client = new ApolloClient({
networkInterface: createNetworkInterface({ uri: 'http://app.local:8001/graphql' }),
});
ReactDOM.render(
<ApolloProvider client={client}>
<BrowserRouter>
<div>
<Route exactly path="/" component={MainComponent} />
<Route path="/about" component={AboutComponent} />
</div>
</BrowserRouter>
</ApolloProvider>,
document.getElementById('tourapp')
)
Then there is the main.jsx:
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
class MainComponent extends Component {
render() {
return <div>
<h1>Hello World</h1>
<p><Link to="/about">About</Link></p>
</div>;
}
}
export default MainComponent
Does anyone have an idea why the router context is not passed? This is almost straightfoward from the docs.
Do this, the link has to be inside the Router tag
<div>
<nav className="navbar navbar-default">
<div className="container-fluid">
<div className="navbar-header">
<a className="navbar-brand" href="#">WebSiteName</a>
</div>
<ul className="nav navbar-nav">
<li className="active"><Link to="/">Home</Link></li>
<li><Link to='/about'>About</Link></li>
</ul>
</div>
</nav>
<Switch>
<Route exact path="/" component={Weather}/>
<Route path="/about" component={About}/>
</Switch>
</div>
</Router>

React changing route breaks height with layout

I have a React application where if I change the route to a page with a small height the entire body doesn't have a max height for the window (the html does have full height).
I have a standard index.html setup here
<html>
<body>
<div id="app"></div>
<script src="client.min.js"></script>
</body>
</html>
Then here's my App.js file:
import React from "react"
import ReactDOM from "react-dom"
import {Router, hashHistory} from "react-router"
import routes from "./Routes"
const app = document.getElementById('app')
ReactDOM.render((
<Router history={hashHistory} routes={routes()}>
</Router>
), app)
And here's my Routes.js file:
import React from "react"
import {Route, IndexRoute} from "react-router"
import Layout from "./Layout"
import About from "./pages/About"
import Home from "./pages/Home"
import NotFound from "./pages/NotFound"
import Register from "./pages/Register"
import SignIn from "./pages/SignIn"
import Terms from "./pages/Terms"
export default() => {
return (
<Route name="root" path="/" component={Layout}>
<IndexRoute component={Home}/>
<Route path="/about" component={About}/>
<Route path="/signin" component={SignIn}/>
<Route path="/register" component={Register}/>
<Route path="/terms" component={Terms}/>
<Route path="*" component={NotFound}/>
</Route>
)
}
Finally here's my Layout.js:
import React from "react"
import ReactDOM from "react"
import DevTool from 'mobx-react-devtools'
import Control from "./components/layout/Control"
import Footer from "./components/layout/Footer"
import Header from "./components/layout/Header"
import Sidebar from "./components/layout/Sidebar"
export default class Layout extends React.Component {
render() {
const { location } = this.props
return (
<div className="wrapper">
<DevTool /> {/* Remove for PRODUCTION */}
<Header />
<Sidebar />
{this.props.children}
<Footer />
<Control />
<div className="control-sidebar-bg"></div>
</div>
)
}
}
All my routes go to pages with very little content so it doesn't cover the full page. In every case the entire body height wraps to the height of the content while the html remains 100% of with window.
I've tried debugging on everything. There's no padding or margin on the body or html rendered by inspecting the elements. I've also tried adding height and min-height 100% attributes to the body tags with inline styling and still didn't get any decent results.
The page automatically fixes itself as soon as the window resizes or I reload the page but that eliminates a lot of the reason to why I am using React.
Any ideas on what could fix this?
I managed to get a fix, this is quite a specific problem (which I've gather from the lack of response). But in-case anyone else stumbled across a problem like this.
All of my pages components had the following render:
export default class About extends React.Component {
render() {
return (
<div className="content-wrapper">
{/* All my about code goes in here */}
</div>
)
}
}
I ended up removing the content-wrapper classNames from all the page container dividers and did the following to the Layout page:
export default class Layout extends React.Component {
render() {
const { location } = this.props
return (
<div className="wrapper">
<DevTool /> {/* Remove for PRODUCTION */}
<Header />
<Sidebar />
<div className="content-wrapper">
{this.props.children}
</div>
<Footer />
<Control />
<div className="control-sidebar-bg"></div>
</div>
)
}
}
This solved all my problems :)