Comments (14)
@katcu
The issue is in how the code split route loading is set up with the boilerplate. I haven't used System.import
much but you need to move the application of the wrapper to the loadModule
function instead of inside the renderRoute.
If you want to apply the wrapper HOC in the routes file you can do the following:
edit: There can be some unnecessary mount/unmounting when applying HOCs inside getComponent because each time the route is rendered, a new component is returned from the HOC. See #44 for details. This can result in poor performance/subtle bugs. Instead scroll down to see how to apply the HOC inside the Component file
// These are the pages you can go to.
// They are all wrapped in the App component, which should contain the navbar etc
// See http://blog.mxstbr.com/2016/01/react-apps-with-pages for more information
// about the code splitting business
import { getHooks } from './utils/hooks';
import { routerActions } from 'react-router-redux'
import { UserAuthWrapper } from 'redux-auth-wrapper'
const errorLoading = (err) => {
console.error('Dynamic page loading failed', err); // eslint-disable-line no-console
};
const loadModule = (cb, hoc) => (componentModule) => {
if (hoc) {
cb(null, hoc(componentModule.default));
} else {
cb(null, componentModule.default);
}
};
const UserIsAuthenticated = UserAuthWrapper({
authSelector: state => null,
predicate: authData=>false,
redirectAction: routerActions.replace,
wrapperDisplayName: 'UserIsAuthenticated'
});
export default function createRoutes(store) {
// create reusable async injectors using getHooks factory
const { injectReducer, injectSagas } = getHooks(store);
return [
{
path: '/',
name: 'home',
getComponent(nextState, cb) {
const importModules = Promise.all([
System.import('containers/HomePage/reducer'),
System.import('containers/HomePage/sagas'),
System.import('containers/HomePage'),
]);
const renderRoute = loadModule(cb, UserIsAuthenticated);
importModules.then(([reducer, sagas, component]) => {
injectReducer('home', reducer.default);
injectSagas(sagas.default);
renderRoute(component);
});
importModules.catch(errorLoading);
},
}, {
path: '/features',
name: 'features',
getComponent(nextState, cb) {
System.import('containers/FeaturePage')
.then(loadModule(cb))
.catch(errorLoading);
},
}, {
path: '*',
name: 'notfound',
getComponent(nextState, cb) {
System.import('containers/NotFoundPage')
.then(loadModule(cb))
.catch(errorLoading);
},
},
];
}
Alternatively, you could move the user wrapper into the component definition
Using decorators: (assuming you add the transform-decorators-legacy
to your babel plugins)
@UserIsAuthenticated
export class HomePage extends React.Component {
...
Or just regular HOC application:
...
// Wrap the component to inject dispatch and state into it
export default UserIsAuthenticated(connect(createSelector(
selectRepos(),
selectUsername(),
selectLoading(),
selectError(),
(repos, username, loading, error) => ({ repos, username, loading, error })
), mapDispatchToProps)(HomePage));
from redux-auth-wrapper.
@mjrussell Thank you for looking into this. The way that use System.import
to import components led to the issue. and as you said, it's difficult integrating it with other NICE modules. I've just changed to a similar boilerplate, issues resolved and everything works as expected.
Thanks again for the nice clean wrapper 👍
from redux-auth-wrapper.
@mjrussell
I simply did the follow steps, then visit http://localhost:3000/features . it should redirect me to /login, right?
Clone this repo using
$ git clone --depth=1 https://github.com/mxstbr/react-boilerplate.git
Run$ npm run setup
to install dependencies and clean the git repo.
At this point you can run$ npm start
to see the example app at http://localhost:3000.
npm install --save redux-auth-wrapper
change the /app/routes.js code as following:
// These are the pages you can go to.
// They are all wrapped in the App component, which should contain the navbar etc
// See http://blog.mxstbr.com/2016/01/react-apps-with-pages for more information
// about the code splitting business
import { getHooks } from './utils/hooks';
import { routerActions } from 'react-router-redux'
import { UserAuthWrapper } from 'redux-auth-wrapper'
const errorLoading = (err) => {
console.error('Dynamic page loading failed', err); // eslint-disable-line no-console
};
const loadModule = (cb) => (componentModule) => {
cb(null, componentModule.default);
};
const UserIsAuthenticated = UserAuthWrapper({
authSelector: state => null,
//authSelector: null,
predicate: authData=>false,
redirectAction: routerActions.replace,
wrapperDisplayName: 'UserIsAuthenticated'
})
export default function createRoutes(store) {
// create reusable async injectors using getHooks factory
const { injectReducer, injectSagas } = getHooks(store);
return [
{
path: '/',
name: 'home',
getComponent(nextState, cb) {
const importModules = Promise.all([
System.import('containers/HomePage/reducer'),
System.import('containers/HomePage/sagas'),
System.import('containers/HomePage'),
]);
const renderRoute = loadModule(cb);
importModules.then(([reducer, sagas, component]) => {
injectReducer('home', reducer.default);
injectSagas(sagas.default);
renderRoute(UserIsAuthenticated(component));
});
importModules.catch(errorLoading);
},
}, {
path: '/features',
name: 'features',
getComponent(nextState, cb) {
System.import('containers/FeaturePage')
.then(loadModule(cb))
.catch(errorLoading);
},
}, {
path: '*',
name: 'notfound',
getComponent(nextState, cb) {
System.import('containers/NotFoundPage')
.then(loadModule(cb))
.catch(errorLoading);
},
},
];
}
from redux-auth-wrapper.
@mjrussell your approach work like magic!
Thank you so much!
from redux-auth-wrapper.
@katcu do you have a branch you are trying this on that I could look at? I haven't used that boilerplate but it should integrate cleanly
from redux-auth-wrapper.
hold on pls... @mjrussell
from redux-auth-wrapper.
Hi, pls check out my branch of issue repoduction https://github.com/katcu/redux-form-with-react-boilerplate/tree/redux-auth-wrapper-with-react-boilerplate
from redux-auth-wrapper.
@katcu thanks Im going to look into this today
from redux-auth-wrapper.
Recently solved this problem thanks to this issue. I noticed this important warning in main page that:
If you are using getComponent in React Router you should not apply the auth-wrapper inside getComponent. This will cause React Router to create a new component each time the route changes.
I guess we can't use
const loadModule = (cb, hoc) => (componentModule) => {
approach.
from redux-auth-wrapper.
@hurkanyakay Yeah good point. We realized afterwards that the loadModule
approach can have some weird edge cases. See #44 for more details. That issue prompted the warning in the README but I never came back to this issue. Im going to edit my original suggestion to encourage using the HOC in the component file.
from redux-auth-wrapper.
Hi all,
I am still a bit lost on the best way to go about getting this setup to work with my project built with the react-boilerplate. I want/need to run this as a hoc but it is not apparent to me what I need to get it other than my export for the component I want to wrap needs to be altered in the manner provided mjrussel above. But, I do not know what imports are needed or where to define my const for UserIsAuthenticated because they are not in the example for hoc. I know I am likely missing something simple so I apologize in advance if its a no brainer.
from redux-auth-wrapper.
@JustinJKlein it is up to you to decide where you want to define your HOC wrappers. I see many examples (and my own projects) create a file authWrappers.js
in which you define the HOC and then they import it either into their Route definition file or their Component definition file. Because you are using react-boilterplate with System.import, you need to apply them inside the Component definition file.
So it might look something like:
authWrappers.js
import { UserAuthWrapper } from 'redux-auth-wrapper'
// Redirects to /login by default
export const UserIsAuthenticated = UserAuthWrapper({
authSelector: state => state.user, // how to get the user state
redirectAction: routerActions.replace, // the redux action to dispatch for redirect
wrapperDisplayName: 'UserIsAuthenticated' // a nice name for this auth check
});
MyComponent.js
import React, { Component } from 'react';
import { UserIsAuthenticated } from './authWrappers';
class MyComponent extends Component {
render() {
return <h1>Renders a thing</h1>;
}
}
export default UserIsAuthenticate(MyComponent);
from redux-auth-wrapper.
Hi there,
im currently trying to add auth to my navigation bar (based react-boilerplate). After some help from @mjrussell yesterday, i could make it work for containers generelly (thanks mate :) )
However now i want to use this approach (readme code example):
// Admin Authorization, redirects non-admins to /app and don't send a redirect param
const UserIsAdmin = UserAuthWrapper({
authSelector: state => state.user,
redirectAction: routerActions.replace,
failureRedirectPath: '/app',
wrapperDisplayName: 'UserIsAdmin',
predicate: user => user.isAdmin,
allowRedirectBack: false
})
// Now to secure the component: first check if the user is authenticated, and then check if the user is an admin
<Route path="foo" component={UserIsAuthenticated(UserIsAdmin(Admin))}/>
My Header(navigation) container looks like this:
class Header extends React.Component { // eslint-disable-line react/prefer-stateless-function
render() {
return (
<div>
<NavBar>
<HeaderLink to="/front">
<FormattedMessage {...messages.front} />
</HeaderLink>
<HeaderLink to="/admin">
<FormattedMessage {...messages.admin} />
</HeaderLink>
<Button onClick={this.props.onClickLogout}>
<FormattedMessage {...messages.logout} />
</Button>
</NavBar>
</div>
);
}
}
I would like to enable/disable HeaderLinks Component using a authWrapper.
Could you please help me out to find a fitting solution?
Thanks in advance! :)
from redux-auth-wrapper.
@LearningDave please see the section in the Readme on Hiding and Alternate Components which is I think what you are asking. You dont want the redirection in this case
from redux-auth-wrapper.
Related Issues (20)
- [Possible Bug] Async Validation in a multi-step form HOT 1
- How to make chunk js with react-router HOT 1
- Error in UserAuthWrapper
- Hande logout when expired token in axios interceptors but not redirect to login page HOT 2
- Misleading naming of authenticatedSelector HOT 2
- Example with react 16.x HOT 1
- Reducer not yet defined HOT 2
- Usage with react-cookies
- not running when am trying do npm start HOT 1
- connectedReduxRedirect is missing HOT 1
- Deprecated lifecycle method in redirect.js HOT 7
- Doesn't work with latest react HOT 3
- Type {} is missing the following properties from type Readonly<InjectedAuthProps> HOT 1
- ES6 Module - Error when using with Electron HOT 2
- redirect.js replace UNSAFE_componentWillMount with componentDidMount HOT 6
- No question mark befor query param on redirect HOT 2
- Versioning Order HOT 4
- React-router v6 HOT 9
- Infinite loop (redirect ) with nesting wrappers HOT 1
- Call for mantainers! HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from redux-auth-wrapper.