Zoeken…
Invoering
Dit document laat zien hoe ReactRouter te gebruiken met Meteor en React. Van nul tot een werkende app, inclusief rollen en authenticatie.
Ik zal elke stap met een voorbeeld tonen
1- Maak het project
2- Voeg React + ReactRouter toe
3- Accounts toevoegen
4- Voeg rollenpakketten toe
Maak het project
1- Installeer eerst https://www.meteor.com/install
2- Maak een project. ( --bare
is om een leeg project te maken)
meteor create --bare MyAwesomeProject
3- Maak de minimale bestandsstructuur ( -p
om tussenliggende mappen te maken):
cd MyAwesomeProject
mkdir -p client server imports/api imports/ui/{components,layouts,pages} imports/startup/{client,server}
4- Maak nu een HTML-bestand in client / main.html
<head>
<meta charset="utf-8">
<title>My Awesome Meteor_React_ReactRouter_Roles App</title>
</head>
<body>
Welcome to my Meteor_React_ReactRouter_Roles app
</body>
5- Zorg ervoor dat het werkt: (3000 is de standaardpoort, dus je kunt de '-p 3000' overslaan)
meteor run -p 3000
en het openen van uw browser op 'localhost: 3000'
Notitie:
Ik sla enkele andere bestanden over die je moet maken om dingen korter te maken. In het bijzonder moet u enkele index.js-bestanden maken in de client , import / startup / {client, server} en servermappen .
U kunt een volledig voorbeeld bekijken op https://github.com/rafa-lft/Meteor_React_Base . Zoek naar tag Step1_CreateProject
React + ReactRouter toevoegen
cd MyAwesomeProject
indien nodig naar uw projectmap- cd MyAwesomeProject
1- Voeg react en react-router toe
meteor npm install --save [email protected] [email protected] [email protected]
2- Bewerk client / main.html en vervang de inhoud zal zijn:
<body>
<div id="react-root"></div>
</body>
Wat de reactRouter ook besluit te tonen, deze wordt weergegeven in het element '# react-root'
3- Maak het lay-outbestand in import / ui / layouts / App.jsx
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
{this.props.children}
</div>
);
}
}
App.propTypes = {
children: PropTypes.node
};
export default App;
4- Maak het Routes-bestand in import / startup / client / Routes.jsx
import ReactDOM from 'react-dom';
import React, { Component } from 'react';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import App from '../../ui/layouts/App.jsx';
import NotFound from '../../ui/pages/NotFound.jsx';
import Index from '../../ui/pages/Index.jsx';
class Routes extends Component {
constructor(props) {
super(props);
}
render() {
return (
<Router history={ browserHistory }>
<Route path="/" component={ App }>
<IndexRoute name="index" component={ Index }/>
<Route path="*" component={ NotFound }/>
</Route>
</Router>
);
}
}
Routes.propTypes = {};
Meteor.startup(() =>{
ReactDOM.render(
<Routes/>,
document.getElementById('react-root')
);
});
Notitie:
Ik sla enkele andere bestanden over die je moet maken om dingen korter te maken. Controleer met name op invoer / ui / pagina's {Index.jsx, NotFound.jsx}.
U kunt een volledig voorbeeld bekijken op https://github.com/rafa-lft/Meteor_React_Base . Zoek naar tag Step2_ReactRouter
Stap 3- Accounts toevoegen
cd MyAwesomeProject
indien nodig naar uw projectmap- cd MyAwesomeProject
1- Accounts pakketten toevoegen: meteor add accounts-base accounts-password react-meteor-data
2- Voeg de routes toe om in te loggen en te registreren pagina's in import / startup / Routes.jsx De methode render () is als volgt:
render() {
return (
<Router history={ browserHistory }>
<Route path="/" component={ App }>
<IndexRoute name="index" component={ Index }/>
<Route name="login" path="/login" component={ Login }/>
<Route name="signup" path="/signup" component={ Signup }/>
<Route name="users" path="/users" component={ Users }/>
<Route name="editUser" path="/users/:userId" component={ EditUser }/>
<Route path="*" component={ NotFound }/>
</Route>
</Router>
);
}
Notitie:
Ik sla enkele andere bestanden over die je nodig hebt om dingen korter te maken. Controleer met name import / startup / server / index.js import / ui / layouts / {App, NavBar} .jsx en import / ui / pagina's / {Login, Aanmelden, Gebruikers, EditUser} .jsx
U kunt een volledig voorbeeld bekijken op https://github.com/rafa-lft/Meteor_React_Base . Zoek naar tag Step3_Accounts
Rollen toevoegen
1- Rollenpakket toevoegen ( https://github.com/alanning/meteor-roles)
meteor add alanning:roles
2- Maak enkele rolconstanten. In bestandsimport / api / accounts / role.js
const ROLES = {
ROLE1: 'ROLE1',
ROLE2: 'ROLE2',
ADMIN: 'ADMIN'
};
export default ROLES;
3- Ik zal niet laten zien hoe rollen op een gebruiker toe te voegen / bij te werken, ik zal alleen vermelden dat je aan serverzijde gebruikersrollen kunt instellen door Roles.setUserRoles(user.id, roles);
Kijk voor meer info op https://github.com/alanning/meteor-roles en http://alanning.github.io/meteor-roles/classes/Roles.html
4- Ervan uitgaande dat u alle accounts en rollenbestanden al hebt ingesteld (zie het volledige voorbeeld in https://github.com/rafa-lft/Meteor_React_Base . Zoek naar tag Step4_roles ), kunnen we nu een methode maken die verantwoordelijk is voor het toestaan van ( of niet) toegang tot de verschillende routes. In invoer / opstarten / client / Routes.jsx
class Routes extends Component {
constructor(props) {
super(props);
}
authenticate(roles, nextState, replace) {
if (!Meteor.loggingIn() && !Meteor.userId()) {
replace({
pathname: '/login',
state: {nextPathname: nextState.location.pathname}
});
return;
}
if ('*' === roles) { // allow any logged user
return;
}
let rolesArr = roles;
if (!_.isArray(roles)) {
rolesArr = [roles];
}
// rolesArr = _.union(rolesArr, [ROLES.ADMIN]);// so ADMIN has access to everything
if (!Roles.userIsInRole(Meteor.userId(), rolesArr)) {
replace({
pathname: '/forbidden',
state: {nextPathname: nextState.location.pathname}
});
}
}
render() {
return (
<Router history={ browserHistory }>
<Route path="/" component={ App }>
<IndexRoute name="index" component={ Index }/>
<Route name="login" path="/login" component={ Login }/>
<Route name="signup" path="/signup" component={ Signup }/>
<Route name="users" path="/users" component={ Users }/>
<Route name="editUser" path="/users/:userId" component={ EditUser }
onEnter={_.partial(this.authenticate, ROLES.ADMIN)} />
{/* ********************
Below links are there to show Roles authentication usage.
Note that you can NOT hide them by
{ Meteor.user() && Roles.userIsInRole(Meteor.user(), ROLES.ROLE1) &&
<Route name=.....
}
as doing so will change the Router component on render(), and ReactRouter will complain with:
Warning: [react-router] You cannot change <Router routes>; it will be ignored
Instead, you can/should hide them on the NavBar.jsx component... don't worry: if someone tries to access
them, they will receive the Forbidden.jsx component
*************/ }
<Route name="forAnyOne" path="/for_any_one" component={ ForAnyone }/>
<Route name="forLoggedOnes" path="/for_logged_ones" component={ ForLoggedOnes }
onEnter={_.partial(this.authenticate, '*')} />
<Route name="forAnyRole" path="/for_any_role" component={ ForAnyRole }
onEnter={_.partial(this.authenticate, _.keys(ROLES))}/>
<Route name="forRole1or2" path="/for_role_1_or_2" component={ ForRole1or2 }
onEnter={_.partial(this.authenticate, [ROLES.ROLE1, ROLES.ROLE2])} />
<Route name="forRole1" path="/for_role1" component={ ForRole1 }
onEnter={_.partial(this.authenticate, ROLES.ROLE1)}/>
<Route name="forRole2" path="/for_role2" component={ ForRole2 }
onEnter={_.partial(this.authenticate, ROLES.ROLE2)} />
<Route name="forbidden" path="/forbidden" component={ Forbidden }/>
<Route path="*" component={ NotFound }/>
</Route>
</Router>
);
}
}
We hebben een onEnter- trigger toegevoegd aan sommige routes. Voor die routes passeren we ook welke Rollen mogen betreden. Merk op dat de onEnter callback oorspronkelijk 2 params ontvangt. We gebruiken de gedeeltelijke underscore ( http://underscorejs.org/#partial) om er nog een toe te voegen (rollen) De authenticatiemethode (aangeroepen door onEnter) ontvangt de rollen en:
- Controleer of de gebruiker helemaal is ingelogd. Als dit niet het geval is, wordt u omgeleid naar '/ login'.
- Als rollen === '*' gaan we ervan uit dat elke ingelogde gebruiker kan deelnemen, dus we staan het toe
- Anders controleren we of de gebruiker is toegestaan (Roles.userIsInRole) en zo niet, dan verwijzen we door naar verboden.
- Optioneel kunt u een regel oncommentariëren, zodat ADMIN toegang heeft tot alles.
De code bevat verschillende voorbeelden van verschillende routes die voor iedereen zijn toegestaan (geen onEterterugbellen), voor elke aangemelde gebruiker, voor elke aangemelde gebruiker met ten minste 1 rol en voor specifieke rollen.
Merk ook op dat ReactRouter (althans op versie 3) het niet toelaat om de routes op Render te wijzigen. Je kunt de routes dus niet verbergen binnen Routes.jsx. Om die reden verwijzen we door naar / verboden in de authenticatiemethode.
5- Een veelvoorkomende bug met ReactRouter en Meteor heeft betrekking op het niet weergeven van gebruikersstatusupdates. De gebruiker is bijvoorbeeld uitgelogd, maar we tonen zijn / haar naam nog steeds op de navigatiebalk. Dat gebeurt omdat Meteor.user () is gewijzigd, maar we niet opnieuw renderen.
Die bug kan worden opgelost door Meteor.user () aan te roepen in createContainer. Hier is een voorbeeld ervan, gebruikt in import / ui / layouts / NavBar.jsx:
export default createContainer((/* {params}*/) =>{
Meteor.user(); // so we render again in logout or if any change on our User (ie: new roles)
const loading = !subscription.ready();
return {subscriptions: [subscription], loading};
}, NavBar);
Notitie:
Ik sla enkele andere bestanden over die je nodig hebt om dingen korter te maken. Controleer met name import / startup / server / index.js import / ui / layouts / {App, NavBar} .jsx en import / ui / pagina's / {Login, Aanmelden, Gebruikers, EditUser} .jsx
U kunt een volledig voorbeeld bekijken op https://github.com/rafa-lft/Meteor_React_Base . Zoek naar tag Step4_roles