Call function from component in react Route - javascript

I'm passing props of form component as addcertificate in App.js.
And adding theses values in the state of app.js using add function
I want to convert these :
<Forms addcertificate={this.add} /> to route like this <Route path=":action/id" component={IdentityPage} />
I tried this but getting error:
<Route path=":action/id" component={<Forms addcertificate={this.add} />} />

You can use the render prop instead of the component prop to render some custom JSX.
<Route
path=":action/id"
render={() => <Forms addcertificate={this.add} />}
/>

Related

React Router V6 routed component needs state/props from another routed component

Hello I am using React router for my application. App.js code segment:
<Routes>
<Route path="/" element={<Login navigate={navigate} setOverlays={setOverlays} setToken={setToken} setUser={setUser} />} />
<Route path="/create-account" element={<CreateAccount />} />
<Route path="/projects" element={<Projects token={token} name={user.name} jobTitle={user.jobTitle} navigate={navigate} setOverlays={setOverlays} />} />
<Route path="/individual_project" element={<IndividualProject />} />
</Routes>
The last route (/individual_project) requires props that is located in the projects component. Since I do not have access to the components in App.js how can I create this route.
I also prefer not to move the state variables from the Projects component and pass them down through props.
There are few ways to achieve that:
You can move the individual_project route inside the Projects component like this:
const Projects = () => {
...other logic
return(
<Routes>
<Route path="/individual_project" element={<IndividualProject />} />
</Routes>
)
}
Docs here: https://reactrouter.com/docs/en/v6/getting-started/overview#nested-routes
Alternatively, you could also create a context to wrap the routes. Then, you can retrieve the variables directly from the context:
<Context.Provider value={yourValuesToShare}>
<Routes>
<Route path="/" element={<Login navigate={navigate} setOverlays={setOverlays} setToken={setToken} setUser={setUser} />} />
<Route path="/create-account" element={<CreateAccount />} />
<Route path="/projects" element={<Projects token={token} name={user.name} jobTitle={user.jobTitle} navigate={navigate} setOverlays={setOverlays} />} />
<Route path="/individual_project" element={<IndividualProject />} />
</Routes>
</Context.Provider>
Docs here: https://reactjs.org/docs/context.html
For this kind of scenarios , using Context API is recommended .its more precise and cleaner that the other techniques.
React docs
Context api is used to access state from any component so react context api is recommended

Should I be using functions instead of classes for pages in ReactJS?

I've noticed React Router DOM (v6) is now using functions in their help guides in regards to pages instead of using classes.
Previously used classes like so:
export class Login extends React.Component {
render() {
return <p>test</p>
}
}
However, after trying the latest version of React Router DOM I would receive an empty page for the navigation route.
import {Login} from "./js/components/Auth/Login";
function App() {
return <h2>Test</h2>
}
if (document.getElementById('app')) {
ReactDOM.render(
<BrowserRouter>
<Routes>
<Route path="/" element={<App />} />
<Route path="/login" component={() => <Login />} />
</Routes>
</BrowserRouter>, document.getElementById('app'))
}
App works fine ('/' route), but /login returns an empty page with no error..
Login refers to a class that uses render() and returns <p>test</p>
Am I doing something incorrectly? Are libraries leaning towards functions instead of class components?
This guide seems to be only using functions for components.
https://reactrouter.com/docs/en/v6/getting-started/tutorial
Class vs Function components is irrelevant in RRDv6, they simply render React components specified as JSX, not as a reference to a component, and not as a function returning JSX. There is also no render or component props, the Route components now use only element to render the route components.
<Routes>
<Route path="/" element={<App />} />
<Route path="/login" element={<Login />} />
</Routes>

What is wrong with the structure of my 'BrowserRouter', 'Routes' and 'Route' in my function App()?

I am attempting to follow a tutorial while learning React.JS and I am running into an issue because the tutorial is using an older version of React and I am stuck trying to figure out how to use BrowserRouter, Routes, and Route.
Can anyone assist me in trying to re-structure the code so it works with the updated version of React? I have tried reading through documentation and tried to mix around a few solutions with no success. Any help is much appreciated!
import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import "bootstrap/dist/css/bootstrap.min.css";
import Navbar from "./components/navbar.component.js";
import PortfolioList from "./components/portfolio-list.component";
import EditPortfolio from "./components/edit-portfolio.component";
import CreatePortfolio from "./components/create-portfolio.component";
import CreateUser from "./components/create-user.component";
function App() {
return (
<Routes>
<Navbar />
<br/>
<Route path="/" exact component={PortfolioList} />
<Route path="/edit/:id" exact component={EditPortfolio} />
<Route path="/create" exact component={CreatePortfolio} />
<Route path="/user" exact component={CreateUser} />
</Routes>
);
}
export default App;
The following is the 'error' I'm generating on runtime:
Error: [Navbar] is not a 'Route' component. All component children of
'Routes' must be a 'Route' or 'React.Fragment'
Only Route components and React.Fragments can be a child of the Routes component, and vice-versa. Move the non-Route components out of Routes. The Route component API also changed in version 6, there is no longer render and component props, the routed components are passed to the element prop as JSX, and routes are now always exactly matched, so there's no longer the exact prop as well.
function App() {
return (
<>
<Navbar />
<br/>
<Routes>
<Route path="/" element={<PortfolioList />} />
<Route path="/edit/:id" element={<EditPortfolio />} />
<Route path="/create" element={<CreatePortfolio />} />
<Route path="/user" element={<CreateUser />} />
</Routes>
</>
);
}
you can use the "BrowserRouter" tag followed by the "Switch" tag then you can now use the "Route" tag to specify the path of each component
you can use the "BrowserRouter" tag followed by the "Switch" tag then you can now use the "Route" tag to specify the path of each component.
return (
<>
<BrowserRouter>
<Switch>
<Route path="/" exact component={DashBoard} />
<Route path="/specialistes" exact component={Specialistes} />
<Route path="/findgarages" exact component={FindGarage} />
<Route path="/garages" exact component={Garages} />
</Switch>
</BrowserRouter>
</>
)````

Pass prop value down from login component to routes component

I have a login form setup using and one particular value props.values.userType I need to pass down via props to my index.js file where I render all my routes.
So in my <Login> component I have a <RadioButtonGroup> that renders the 3 types of users available
<RadioButtonGroup
id="userType"
label="User Type"
value={values.userType}
error={errors.userType}
touched={touched.userType}
onBlur={handleBlur}
>
From here the userType exists in formik as props.values.userType
I want to pass this prop value down to my index.js file that renders all my routes.
index.js below
const Routes = () => (
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login" component={FormikLoginForm} />
<PrivateRoute exact path="/admin" component={AdminPage} />
<Route path="/admin/change-password" component={ChangePassword} />
</Switch>
</Router>
);
How can I achieve this?
codesandbox here
Instead of using component as a prop for each <Route />, you can use the render prop to pass props into the component you want to render on that route.
For example in your case, if your component was called Login:
<Route
path='/login'
render={(props) => <Login {...props} userType={props.values.userType} />}
/>
Or something similar depending on your use case.

How to display different components for different users on one route?

I need to show different components in one route.
My router with authorization looks like:
<Route authorize={['admin']} component={Authorization}>
<Route path='/home' component={Home} />
</Route>
And in Authorization component I have to check if the user has a access to this route.
But the question is how to show different components on the same route?
Something like this doesn't work:
<Route authorize={['admin']} component={Authorization}>
<Route path='/home' component={AdminHome} />
</Route>
<Route authorize={['manager']} component={Authorization}>
<Route path='/home' component={MangerHome} />
</Route>
Define only one route and create a wrapper component, inside wrapper component check the condition and render different component.
Like this:
<Route authorize={['manager', 'admin']} component={Authorization}>
<Route path='/home' component={WrapperComponent} />
</Route>
Now from Authorization component pass some bool to WrapperComponent to decide between which component do you want to render.
Inside WrapperComponent:
render(){
if(this.props.isAdmin)
return <Home />
return < MangerHome />
}

Categories

Resources