How to find out what is currently selected? (react-router-dom) - reactjs

How to find out what is currently selected? (React-router-dom)
There is an Auth.js component that should output SignUp or SignIn. How to find out what is currently selected?
<div className="auth">
<div className="auth__intro">
<h1>Auth:</h1>
</div>
<div className="auth__form-intro">
<SignIn /> // or <SignUp />
</div>
</div>
How can I make the registration form open when I click on "Register"?
enter image description here

Using react-router-dom, you would use a <Switch> to display a different component based on the URL and <Link> elements to navigate between the routes. You can see an example here in their documentation on how to achieve this.

Related

Use <a> tag to scroll down to a differnet component in single page react app

I'm creating a portfolio website using React.
It is a single page website and each section of the website is its own separate component.
My navbar component has links at the top that when clicked I want the page to scroll to the corresponding section further down the page. A traditional About is not working. Do I need to use react-router-dom or am I just missing something?
const App = () => {
return (
<div className='app'>
<Navbar />
<Hero />
<About />
<Projects />
<Footer />
</div>
)
}
export default App
You can use the refs to scroll the page to a section . Refs in react have many applications , you can read details on react official page. Here is an example to use ref for scrolling
const Scroll = () => {
const scrollTo = useRef();
return (
<div>
<button onClick = {()=>{scrollTo.current.scrollIntoView()}></button>
.
.
// Your Other divs
.
.
<div ref={scrollTo}>Scrolled</div>
</div>
);
}
You can use the window.scroll() for scrolling page to a coordinate
window.scroll({top:600,left:50,behavior:'smooth'})
Don't know what I was doing wrong but as Drew suggested in his answer, the classic <a> tag does work as expected.
Go forth and use those tags fellow React devs!

how to resolve "Prop `id` did not match. Server: "react-tabs-30" Client: "react-tabs-0" console issue?

i am trying tab in next in next.js, but every time i use it it show a console warning link this Prop `id` did not match. Server: "react-tabs-30" Client: "react-tabs-0", i know it isn't effect my app but it is so annoying. how to solve this waring
<Tabs>
<div className="tab-controler ml-sm-auto">
<TabList className="tab-lists list-inline d-flex flex-wrap nav mb-3" style={{ background: '#F8F8F8' }}>
<Tab className={`${CostCalculatorStyle.PEItem} tab-lists__item`}>Buy & Ship for me</Tab>
<Tab className={`${CostCalculatorStyle.PEItem} tab-lists__item`}>Ship for me</Tab>
</TabList>
</div>
<TabPanel key={"tabpanel_ship"}>
<div className="row">
<div className="col-lg-6">
<ShipForMeForm handleFormValue={handleFormValue} handleProductValue={handleProducts} handleRef={handleRef} />
</div>
<div className="col-lg-6 align-self-center">
<div className="costcalc-empty-thumb text-center">
<Image
src="/assets/topNavbarPages/costCalculator.svg"
alt="Cost Calculator"
width="469"
height="288"
/>
</div>
</div>
</div>
</TabPanel>
<TabPanel key={"tabpanel_buy_ship"}>
<div className="row">
<div className="col-lg-6">
<ShipForMeForm handleFormValue={handleFormValue} handleProductValue={handleProducts} handleRef={handleRef} />
</div>
<div className="col-lg-6 align-self-center">
<div className="costcalc-empty-thumb text-center">
<Image
src="/assets/topNavbarPages/costCalculator.svg"
alt="Cost Calculator"
width="469"
height="288"
/>
</div>
</div>
</div>
</TabPanel>
</Tabs>
as you can see i use react-tabs for tab but i also work on react js where i use the same code but it didn't show this console warning. so my question is why it is happing? and how i can solve it ?
In next js i fixed it like that
import dynamic from 'next/dynamic'
const Tabs = dynamic(import('react-tabs').then(mod => mod.Tabs), { ssr: false }) // disable ssr
import { Tab, TabList, TabPanel } from 'react-tabs'
it work for me
The best solution I know of is just to set the id yourself in the <Tabs> component. Ex: <Tabs id={1}>
See https://github.com/chakra-ui/chakra-ui/issues/4328#issuecomment-890525420 for more details and examples.
NextJs generating code in server side as you know.
This error means that something on the server is different from the Client. This can happen if the client does a re-render.
For example.
export default function Test(props) {
return (
<>
<span>{props.name}</span>
</>
);
}
I have this simple Test component.And I send name (1) prop from another component to this Test component. And if I change this name (to 2) in client using redux (for example I have another name in my redux store) after page generated I get this error.
props did not match server "1" client "2"
To solve this error I need to just not change this name with redux after page generated in server. The data can be change only with user manipulations after page rendered in server.
Same thing happened to me when I use Tabs from react-bootstrap. Koushik Saha's answer can be apply for that also but with a small change. Need to put react-bootstrap instead react-tabs
const Tabs = dynamic(import('react-bootstrap').then(mod => mod.Tabs), { ssr: false })
In case you miss it
If you are using Nextjs + Material-ui, there are actually custom codes that you can/need to include in your _document.js and _app.js to remove the server-side injected CSS so the CSS is recreated when page loads.
As codes changes with mui's and nextjs' version, i will refer you to the repository directly
https://github.com/mui-org/material-ui/tree/master/examples/nextjs/pages
As per the documentation in the react-tabs repo/npmjs.org page (https://www.npmjs.com/package/react-tabs):
import { resetIdCounter } from 'react-tabs';
resetIdCounter();
ReactDOMServer.renderToString(...);
I was having the same issue and called the resetIdCounter function inside my parent component to the tabs structure and cleared up the error.
Not sure if maybe there is a better place to use this function, like maybe in a useEffect hook or something, but I'm going with this for now.

React Router not loading specific component and removing all other components too

I'm learning the basics of React Router. So what I'm making right now has a navigation bar on top and two buttons below this top bar. What I want is for the a table or something of the sort to show up when I press one of the buttons.
The problem is that when I click the button, the URL changes but the all the components vanish. Even the component I want displayed doesn't show and the other components (which ideally should stay) also disappear.
What am I doing wrong here? The code is as follows :-
const Site = () =>
<React.Fragment>
<div className="container-fluid row">
<div className="offset-3 col-sm-4">
<Link to="/A">
<Button value="A"/>
</Link>
</div>
<div className="col-sm-4">
<Link to="/B">
<Button value="B"/>
</Link>
</div>
</div>
<div>
<Route path="/B" component={B}/>
</div>
</React.Fragment>
export default Site;
The Site page has the URL '/Site'.
Edit:
Just thought I'd mention the structure a bit. So for now I have a page with a button. Clicking this button should load the a component (called Base with URL '/Site') which is calling the TopBar and Site components.
Then I have these two buttons - A and B which have their respective URLs.

how to implement website navigation with reactjs

Hi I am developing a website using reactjs. Each page of the website has mainly 3 parts (1. header 2. body 3. footer) . So header and footer will be same for each page and body will keep on changing. Should I create header and footer components and then include them in each page of the website. Is this good design?
How can I highlight navigation menu option for a particular page. For example If I am on contactus page then ContactUs menu option should be highlighted. Similarly If I am one Home Page then "Home" should be highlighted.
In react apps you usually use a router library for this.
A router also takes care of the url in the address bar, so you can save and share links to sub pages in a single page application, and use the browser's back button.
The most popular router for react is called "React Router", but there are other alternatives. It's even possible to write your own router.
React-router's docs has examples of how you can implement this. For the highlighting effect, you can use the component called <NavLink />
Instead of including the header and footer in each page, you start from the outside in. You only put header and footer in once, typically in a main <App />, and then include variable page content inside <Route /> components.
yes you can create 2 components on the top level. they will be header and footer. for navigation; you can use react-router. it will be used to navigate between views. you can put the body component inside your header component your main App structure can be :-
<App>
<HeaderComp/>
<FooterComp/>
</App>
now you can set react-router to change the component being render in body place when any link in the header is clicked. you can also keep the state of currently active view and highlight its color when active.
in react-router v4 you can use switch and route to change between components
<Switch>
<Route exact path='/' component={YourComponent} />
<Route path='/secondcomponent' component={YourSecondComponent} />
<Route path='/thirdcomponent' component={YourthirdComponent} />
</Switch>
this will be your body component , other components like given above will be shown when you click on the link in the head that matches the path in Route tag.
now you header render can be like this.
render(){
return (
<div>
<TopBar/>
<BodyComp/>
<div/>
)
}
the topbar will be fixed and stay on top , the body will have all the space except the margin on top to adjust below the topbar
your topbar can be like this.
render(){
return(
<div className="topBarcontainer">
<Link to="/" >
<div className ="topBarItem">
Home
</div>
</Link>
<Link to="/secondComponent" >
<div className ="topBarItem">
secondComponent
</div>
</Link>
</div>
)
}
as for you want to highlight the current view , you can keep the state array and add give each Link the value from that array , and put onMouseDown on it , when it is clicked it will callback telling the value that is clicked and u will reset all the items background color to default , then you can set the style of that particular active item in your header to active color. you should use inline styling for that instead of className

switching between certain component on a page using nested route in react router

I am trying to create a job site. Following pages shows list of all the jobs which is shown once user hits search button from home page. So basically this is the second page.
In this page i am catching all the search parameter from url and fetching data from api and result is shown as below:
Once the user clicks individual joblist, detail page should load on the same page without changing header and fixed component with unique URL for the detail page. Expected result shown below:
My Problem:
I manage to create a nested Route, which renders detail page on the same page and also has a unique url. But it renders on top of existing job list. I mean if user clicks on joblist1, detail page renders on top of subsiquent list(above list: 2, 3, 4). But expected result is to only render detail page but not list of jobs when individual job list is clicked.
My code: I have only shown part of the code for brevity and simplicity.
1) jobs.js: Passes state data to child component to show list.
return(
<div>
<div>
fixed component
</div>
<div>
<RouteHandler />
<JobLists joblists={this.state.joblists} />
</div>
</div>
)
2) jobList.js: uses .map function to go through all data and handleclick function generate url and opens that url once user clicks individual link. Router catches nested route and loads value inside jobs.js in " ".
handleClick: function(i){
var base_path = window.location.protocol + '//' + window.location.host;
base_path += '/#/jobs-detail';
window.location= base_path;
},
render: function(){
var jobListRow = this.props.joblists.map(function(jobrowobj, i){
return(
<div key={jobrowobj.id} onClick={this.handleClick.bind(this, i)}>
<img src={jobrowobj.logo} alt="" />
<h3>{jobrowobj.title}</h3>
</div>
)
}.bind(this));
return(
<ul id="joblists">
{jobListRow}
</ul>
)
}
3) Route file:
var routes = (
<Route handler={App}>
<DefaultRoute handler={Home} />
<Route name="jobs" path="jobs" handler={Jobs}>
<Route name="jobs-detail" handler={JobDetail} />
</Route>
<NotFoundRoute handler={NotFoundPage} />
</Route>
);
I am not sure what is the best way to switch certain section (component) on a page as in my case switching between joblist component and jobdetail component. As you can see i am only able to load other component on top of existing component which is not the expected result.
Also would appreciate if any hint is given to maintain scroll position on the job list on user hitting back button.
I suggest you to upgrade your react-router to 1.0.0-rc1, and the API is more clear. Your problem is similar to the official introduction. The nested component will be passed as this.props.children, and you can insert it into the jobListRow.
About the scroll position, there's a github issue discussing how to restore it :)

Resources