I have the follow routes in my landing page.
...
<Route exact path='/MainPage' render={(match, history) => {
return <MainPage></MainPage>
}}/>
<Route exact path='/Search' render={(match, history) => {
return <SearchPage></SearchPage>
}}/>
<Route exact path='/Register' render={(match, history) => {
return <RegisterPage></RegisterPage>
}}></Route>
<Route exact path='/HTTP' render={(match, history) => {
return <HTTPPage></HTTPPage>
}}></Route>
...
The problem I'm having is that these pages are rendered immediately when the landing page is opened, which means all the css files in these routes are rendered too. For example, in the SearchPage/index.js I have:
import '../style_sheets/mainComponents.css'
When I open the browser inspector on the landing page I see all of these css files are rendered as style tags in the . A lot of these css files have class selectors which adversely modify how things look on the landing page. Is there a way to suppress the rendering of these routes or simply somehow separate the imported css in the children elements from their parent page?
Related
I'm relatively somewhat new to the whole world of react, DOM, etc.
This probably sounds like a simple issue or a dumb question, bear with me.
My code for the routing stuff looks like:
function App() {
return (
<div className="content">
<SideBar>
<Router>
<Routes>
<Route path="/dashboard" element={Dashboard} />
</Routes>
</Router>
</SideBar>
</div>
);
}
export default App;
My SideBar is a component of a sidebar, it should allow users to click on a button and to navigate to a new page. In this case, a dashboard. However, all pages basically load at the start of me going to my localhost/
I've tested this out due to a console.log loading from the dashboard basically popping up in other places, not just localhost/dashboard.
I'm using MaterialUI, React.
My SideBar.js looks like this:
<List>
{BarData.map((item, key) => {
return (
<ListItemButton
key={key}
onClick={() => {
window.location.pathname = item.link;
}}
Has things removed, but here is my SideBar data (in another folder).
export const BarData = [
{
text: "Dashboard",
icon: <HomeRounded color="#637381" />,
link: "/dashboad",
},
Am I doing something wrong here? I'm completely new to React, DOM, etc. So I'm unsure if this is the best way to go in general.
In short, what I'm trying to achieve is:
Have multiple pages, if a user clicks a button, it'll navigate them to that specific page, in this case a Dashboard.
Not have every page load at once(?) I'm still unsure on why this is, is it due to me importing the dashboard page and the element is grabbing it, not working fully, so it's just loading what the page shows?
Problem
Our application injects other apps which are rendered using Iframes, the user can access these apps via a tab menu. Obviously the iframe src request can take some time, and it is not ideal to perform the request when the user clicks on the tab.
The app should appear as if it is part of our app - i.e. completely seamless and part of our bundle.
What I've Tried - Browser Caching
By simply making a call to the IFrame URL on app load, the browser will cache a majority of the required resources for each app.
To achieve this I created a simple component that renders an IFrame with the required app URL.
const PreloadIframe = props =>
(
<iframe
src={props.url}
></iframe>
);
I then render this component as display:none when the app loads. And when the user clicks on the required tab to load the real iframe, the bundle has already been cached and the transition is nearly seemless.
Problems with this solution
The client makes 2 requests to the app URL, once to cache and once again when it should actually be displayed
This cancels out any optimisation that the caching might provide, as the user must still wait on a response from the web service before they can use the injected app.
Ideally
I would like to set the <PreloadIframe/> component to visible when the user clicks the appropriate tab.
Is it possible to use
Route.render() or
Route.component
To render an existing component, i.e a component that is currently present in the DOM?
I ended up just creating a intermediary component IframeFactory
class IframeFactory extends Component {
componentDidMount() {
this.props.iframeRef.current.setVisible(true);
}
componentWillUnmount() {
this.props.iframeRef.current.setVisible(false);
}
render() {
return null;
}
This component takes a ref to an iframe.
Then in my <Route /> component I simply render this intermdiary component and pass in the appropriate ref.
{injectableApps ? injectableApps.map(app => (
<Route
key={`/${app.id}`}
path={`/${app.name}`}
render={() => (
<IframeFactory iframeRef={app.iframeRef} />
)}
/>
)) : null}
I'm using react-router with react-transition-group to switch between full page components (think a simple book). However sometimes the next page has a few images. Therefore I don't want the next page to load until all the images / included CSS has also loaded. I don't mind having a loader before this transition takes place, waiting for the next component to load.
However I can't find any way to call events on the entire next component loading. componentDidMount() on the incoming component doesn't recognize whether the images have loaded within the new component, so when the next component slides in, the images often aren't loaded, so it's not very smooth.
Here's my CSSTransition and Switch code:
const App = withRouter(({ location }) => (
<TransitionGroup>
<CSSTransition
key={location.key}
classNames='slide'
timeout={1000}
>
<Switch location={location}>
<Route path="/:page" component={Subpage} />
<Route path="/" exact component={Homepage} />
</Switch>
</CSSTransition>
</TransitionGroup>
))
When navigating from one page to another, I would like the user to be automatically scrolled to the top, i.e. scrollTo(0, 0).
According to the react-router docs on scroll restoration the recommended approach is to setup a component ScrollToTop and wrap your routes within this.
While this works well and the user is scrolled to the top for any route nested within the ScrollToTop component, if the component is placed within a Switch component, the Switch does not function like a Switch any longer; meaning that it will render all routes that it matches instead of the first one.
Alternatively, placing the ScrollToTop outside of the Switch, it no longer scrolls the user to the top.
Version: react-router-v4
I'm not sure specifically about the scrolling, but you can attach a listener to browserHistory which may be an easy way to do this (I don't think onUpdate works with v4):
const browserHistory = createBrowserHistory();
browserHistory.listen((location, action) => {
window.scrollTo(0, 0);
});
<Router history={browserHistory} />
I had the same issue what i did was Whenever the is updated it will take the user to the scrollTo(0,0)
<Router onUpdate={() => window.scrollTo(0, 0)} history={createBrowserHistory()}>
...
</Router
If above does not work :
In react-router-v4 scroll Restoration
This is straightforward to handle with a component that will scroll the window up on every navigation, make sure to wrap it in withRouter to give it access to the router’s props:
componentDidUpdate(prevProps) {
if (this.props.location !== prevProps.location) {
window.scrollTo(0, 0)
}
}
render() {
return this.props.children
}
}
Then render it at the top of your app, but below Router
const App = () => (
<Router>
<ScrollToTop>
<App/>
</ScrollToTop>
</Router>
)
Above code is copied from React-Router web guides
I managed to solve this using the react-router-v4 scroll Restoration and placing the ScrollToTop outside of the Switch. Also remember to use withRouter otherwise it won't work.
I have my navigation bar with following contents
+------+-------+-------+
| Home | About | Login |
+------+-------+-------+
Home is vertically scroll-able page with multiple sections (e.g #About and other sections) While login is separate react component which gets rendered on /login route.
Here is my route.js file
<Route path="/" component={App}>
<IndexRoute component={Home}/>
<Route path="/login" component={Login}/>
</Route>
My question is how should I handle navigational changes within page sections?
Currently I am doing it like this:
<li>
<Link to="/#about-us">About</Link>
</li>
and About section within home page is
<div id="about-us">
About us
</div>
Problem with this approach is when I am at login page(/login) and click on About section link (/#about-us) of Home page nothing happens!
Edit:
I am using react-routerV2
React Router currently does not handle scroll behavior for hash anchors.
However, if you're using browser history, in your case, you can just use <a href="#about-us">, and let the browser take care of it.
I've run into the same problem! The fix I'm using is below...
animatedScroll: function(div_to_scroll_to) {
jQuery('html, body').animate({
scrollTop: div_to_scroll_to.offset().top
}, 500);
}
Clicking the About link should trigger an onClick event which calls animatedScroll with the div you want to scroll to (which is a jQuery element in the above code) as the parameter.
This avoids page reloads (which is how the <a href="..." ... fix would work) and requires very little work on your part.
Hopefully the React-Router team will have built handlers for intra-component navigation soon.
Good luck!
Note: Depending on how your page is structured jQuery('html, body') may not be appropriate. This should always just be the parent container. Please let me know if you have any further questions.