ReactJS - component does not load with url parameter - reactjs

Component does not load when I manually enter a url with parameter in the browser's search bar and naturally it says 'not working' in the console but when I click on a button going to '/:username' url from my index page, I don't get any error, it works pretty well. Where am I wrong?
router.js
const Main = () => (
<Switch>
<Route exact path="/login" component={FrontLogin} />
<Route path="/register" component={FrontRegister} />
<IndexRoute exact path="/home" component={FrontHome} />
<IndexRoute exact path="/:username" component={FrontProfile} />
<Redirect to="/home" />
</Switch>
)
index.js
class Index extends Component{
render(){
return(
<Provider {...Store}>
<BrowserRouter>
<Route component= {Main}/>
</BrowserRouter>
</Provider>
)
}
}
ReactDOM.render(<Index/>,document.getElementById('index'))
profile.index.js
const Profile = (props) => {
const {params} = props.match;
const [data, setData] = useState({});
const history = useHistory();
const [refresh, setRefresh] = useState(false);
console.log(props);
if(!props.location.key){
console.log('not working');
}
if (props.location.key) {
useEffect(() => {
axios
.get(
`/api/${params.username}`,
{
headers: {
Authorization:
"Bearer " +
props.AuthStore.appState.user.access_token,
},
}
)
.then((res) => {
if (res.data.username) {
setData(res.data);
setRefresh(true);
}
})
.catch((error) => {
console.log(error);
});
}, [refresh]);
}
console.log(refresh);
ProvideRoute.js
const PrivateRoute = ({
component:Component,
path,
...rest
}) => (
<Route path= {path} {...rest}
render={
props => isLoggedIn ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname:"/login",
state:{
prevLocation:path,
error:'Giriş yapmalısın.'
}
}}/>
)
} />
)
export default withRouter(PrivateRoute);

Related

In react hooks web app, props is not getting correctly in component

In the react hooks web, I have a component called NominatePerson, in that component if the props.role is not admin it should display text Nomination View and if its admin then it should display Dashboard. This is not happening, it always displays Dashboard. Could someone help me to resolve the issue ?
App.js
function App() {
const [role, setRole] = useState();
useEffect(() => {
const fetchData = async () => {
try {
const userEmail = localStorage.getItem("loginEmail");
const res = await Axios.get(
"http://localhost:8000/service/managenomineeaccess",
{ params: { userEmail } }
);
console.log(res.data[0][0].access, "rest.data");
const data = res.data[0][0].access;
setRole(data);
} catch (e) {
console.log(e);
}
};
fetchData();
}, []);
const switchAdmin = (
<Switch>
<Route exact path='/' component={() => <Login role={role} />} />
<ProtectedRoute exact path='/dashboard' component={DashboardLayout} />
<ProtectedRoute exact path='/manageNominees' component={ManageNominees} />
<Route path='/nominatePerson' exact component={NominatePerson} />
<Route path='/nominationView' exact component={NominationView} />
</Switch>
);
const switchUser = (
<Switch>
<Route exact path='/' component={Login} />
<Route
path='/nominatePerson'
exact
component={() => <NominatePerson role={role} />}
/>
<Route
path='/nominationView'
exact
component={() => <NominationView role={role} />}
/>
<Route component={NominationView} />
</Switch>
);
return (
<Router>
<div>
<ThemeProvider theme={theme}>
<GlobalStyles />
{role === "admin" ? switchAdmin : switchUser}
</ThemeProvider>
</div>
</Router>
);
}
export default App;
NominatePerson
const NominatePerson = (props) => {
return (
<div className='leftNavItem'>
<a>
<Link
to={props.role ? "/nominationView" : "/dashboard"}
className='nav-link'
>
<b>{props.role ? "Nomination View" : "Dashboard"}</b>
</Link>
</a>
</div>
)
}
server.js // get service
app.get("/service/managenomineeaccess", async (req, res) => {
try {
let userEmail = req.query.userEmail;
let data = await sequelize.query(
`SELECT access FROM devchoice.managenominees where email="${userEmail}";`
);
res.status(200).send(data);
} catch (e) {
res.status(500).json({ fail: e.message });
}
});

React-router-dom not re rendering Switch when state is change

I am using aws-amplify, react-hook in my project. The app have some private Routes has been define below:
const ProtectedRoute = ({render: C, props: childProps, ...rest}) => {
return (
<Route
{...rest}
render={rProps =>
(childProps) ? (
<C {...rProps} {...childProps} />
) : (
<Redirect
to={`/login?redirect=${rProps.location.pathname}${
rProps.location.search
}`}
/>
)
}
/>
);
}
In App.js, we change childProps to define whether user is login or not. But when childProps change, Switch not re rendering. What is the way to force React re rendering its Route because isAuthenticated is change but ProtectedRoute is not rerender.
const [isAuthenticated, userHasAuthenticated] = useState(null);
useEffect(() => {
onLoad();
}, []);
async function onLoad() {
try {
let user = await Auth.currentSession();
if (user.accessToken.payload) {
userHasAuthenticated(user.accessToken.payload);
}
} catch (e) {
if (e !== 'No current user') {
alert(e);
}
}
}
.....
const childProps = isAuthenticated;
return (
<ApolloProvider client={client} >
<div className="App">
<BrowserRouter>
<Route path='/'>
<div>
<Switch>
<Route path='/login' render={props => <Login {...props}/>} exact/>
<ProtectedRoute
exact
path='/admin/:name'
render={()=> <Admin />}
props={childProps}
/>
<Route path='/' render={props => <User {...props} />}/>
</Switch>
</div>
</Route>
</BrowserRouter>
</div>
</ApolloProvider>)
The route only renders again when you enter that URL again. You are doing a Redirect, meaning it will never have a chance to enter the same URL after authentication is complete. You should delay rendering the protected route until you have confirmed authentication:
useEffect(() => {
async function onLoad() {
try {
let user = await Auth.currentSession();
userHasAuthenticated(!!user.accessToken.payload);
} catch (e) {
if (e !== 'No current user') {
alert(e);
}
}
}
onLoad();
}, []);
...
const ProtectedRoute = ({render: C, props: childProps, ...rest}) => {
if (childProps === null) {
// app still waiting authentication
return 'Loading...';
}
return (
<Route
{...rest}
render={rProps =>
(childProps) ? (
<C {...rProps} {...childProps} />
) : (
<Redirect
to={`/login?redirect=${rProps.location.pathname}${
rProps.location.search
}`}
/>
)
}
/>
);
}

How do I prevent infinite loop when isAuthenticated is undefined in React Router?

I'm getting an infinite render loop because the value of isSignedIn is initially undefined. How do I solve this?
Container.jsx
class Container extends Component {
componentDidMount() {
this.props.onFetchUserInit();
}
render() {
const { path } = this.props.match;
const isSignedIn = this.props.sessionData.signed_in;
return (
<Switch>
<ProtectedRouteWrapper scope='employers'>
<Route exact path={path}>
<div>
<HeaderContainer />
<WelcomeContainer />
</div>
</Route>
</ProtectedRouteWrapper>
<Route path={`${path}/dashboard`}>
<HeaderContainer />
<EmployerDashboardContainer />
</Route>
</Switch>
)
}
}
const mapStateToProps = state => ({
sessionData: state.session.userData
});
const mapDispatchToProps = dispatch => ({
onFetchUserInit: () => dispatch(fetchUserInit()),
});
ProtectedRouteWrapper.jsx
const ProtectedRouteWrapper = ({ children, ...rest }) => {
const isSignedIn = useSelector(state => state.session.userData.signed_in)
return (
<Route
{...rest}
render={({ location }) =>
isSignedIn === true ? ( children ) : <LoginContainer />
}
/>
);
}
You can add a route to LoginContainer component and redirect user to it in ProtectedRouteWrapper.
class Container extends Component {
componentDidMount() {
this.props.onFetchUserInit();
}
render() {
const { path } = this.props.match;
const isSignedIn = this.props.sessionData.signed_in;
return (
<Switch>
<ProtectedRouteWrapper scope='employers'>
<Route exact path={path}>
<div>
<HeaderContainer />
<WelcomeContainer />
</div>
</Route>
</ProtectedRouteWrapper>
<Route path={`${path}/dashboard`}>
<HeaderContainer />
<EmployerDashboardContainer />
</Route>
<Route path={`/login`}>
<LoginContainer />
</Route>
</Switch>
)
}
}
const mapStateToProps = state => ({
sessionData: state.session.userData
});
const mapDispatchToProps = dispatch => ({
onFetchUserInit: () => dispatch(fetchUserInit()),
});
Adding reload:
const ProtectedRouteWrapper = ({ children, ...rest }) => {
const isSignedIn = useSelector(state => state.session.userData.signed_in)
return (
<Route
{...rest}
render={({ location }) =>
isSignedIn === true ? ( children ) :
<Redirect to={{ pathname: "/login", state: { from: props.location } }} />
}
/>
);
}

reactJs App js - passing incoming data as props

How do I pass data from the app.js file as json to the app.js file as props. I want to display the incoming data as json in the whole project.
I want to pass the incoming data as props.
{id: 1, first_name: "", last_name: "", profile: {…}}
{id: 1, userKey: "0245abb9-2837-4f37-ae02-9be1b88887ef", gsmNo: "05442221111", phone: ""}
Thank you from now
import React, { Component } from 'react';
import {BrowserRouter, Route, Switch } from 'react-router-dom';
// import { renderRoutes } from 'react-router-config';
import './App.scss';
import {updateCustomer} from "../components/helpers/actions/customerActions";
import { connect } from "react-redux";
const loading = () => <div className="animated fadeIn pt-3 text-center">Loading...</div>;
// Containers
const DefaultLayout = React.lazy(() => import('../containers/DefaultLayout'));
// Pages
const Login = React.lazy(() => import('../views/Pages/Login'));
const Register = React.lazy(() => import('../views/Pages/Register'));
const Page404 = React.lazy(() => import('../views/Pages/Page404'));
const Page500 = React.lazy(() => import('../views/Pages/Page500'));
class App extends Component {
// eslint-disable-next-line no-useless-constructor
constructor(props) {
super(props);
this.state = {
profile_items: [ ]
}
}
componentDidMount() {
this.props.onUpdateCustomer({ID: "-1", customerKey: "-1"});
console.log("app.js");
return fetch('http://127.0.0.1:8000/api/account/me',
{
headers: {
Authorization: `Bearer ${localStorage.getItem("id_token")}`,
"Content-Type": "application/json"
},
})
.then((response) => response.json() )
.then((responseData) => {
console.log(responseData);
this.setState({
profile_items: responseData
});
//console.log(this.state.profile_items)
return responseData;
})
.catch(error => console.warn(error));
}
render() {
return (
<BrowserRouter>
<React.Suspense fallback={loading()}>
<Switch >
<Route exact path="/login" name="Login Page" render={props => <Login {...props}/>} />
<Route exact path="/register" name="Register Page" render={props => <Register {...props}/>} />
<Route exact path="/404" name="Page 404" render={props => <Page404 {...props}/>} />
<Route exact path="/500" name="Page 500" render={props => <Page500 {...props}/>} />
<Route path="/" name="Home" render={props => <DefaultLayout {...props}/>} />
</Switch>
</React.Suspense>
</BrowserRouter>
);
}
}
const mapStateToProps = (state, props) => {
return state;
};
const mapDispatchToProps = {
onUpdateCustomer: updateCustomer,
};
export default connect(mapStateToProps, mapDispatchToProps) (App );
You can use HOC to pass props into Lazy Component. With my option, I think it work.
Create HOC:
const LazyHOC = ({ component: Component, ...rest }) => (
<Component {...rest} />
)
import your component:
const ComponentExample = React.lazy(() => import('./components/ComponentExample'));
Wrap Component with HOC:
const LazyComponentExample = props => <LazyHOC component={ComponentExample} {...props}/>
And you can pass props like this:
<React.Suspense fallback={loading()}>
<Switch >
<Route
exact path="/login"
name="Component example"
render={<LazyComponentExample props={...} />} />
</Switch>
</React.Suspense>

React Routing not rendering

I am using React routing v4 for a application that has a login and a home page once a dumb auth is done.
As of this point I have this LoadComponent.jsx in my index.js file:
class LoadComponent extends Component {
state = {
isLoggedOn: false,
};
onLoginCheck = (name, password) => {
console.log(name, password);
if (name && password) {
setTimeout(name, 100); // fake async
console.log('set the timeout');
}
this.setState({
isLoggedOn: true,
});
};
checkAuth = () => {
const { isLoggedOn } = this.state;
console.log('checking auth: ', isLoggedOn);
return (isLoggedOn);
};
render() {
return (
<BrowserRouter >
<Switch>
<Header isLogged={this.checkAuth()} />
<Route path="/login" render={props => <Login isLoggedOn={this.state.isLoggedOn} onLoggedInCheck={this.onLoginCheck} {...props} />} />
<PrivateRoute path="/" component={App} authenticated={this.state.isLoggedOn} />
</Switch>
</BrowserRouter>
);
}
}
My privateRouter looks like the following :
const PrivateRoute = ({
component, exact = false, path, authenticated,
}) => {
console.log('here : ', authenticated);
return (
<Route
exact={exact}
path={path}
render={props => (
authenticated ? (
React.createElement(component, props)
) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location },
}}
/>
)
)}
/>
);
};
export default PrivateRoute;
The only thing that is rendered on the page is the Header component which makes sense, but the PrivateRoute component is not functioning since at first the Login component should be displaying. Im not sure what I am doing wrong here since I have followed the react router Redirect Auth example to some degree.

Resources