11 Multi-Page-Feeling in a Single-Page-App: Routing
210 Useful Resources & Links
209 Wrap up
Assignment 3: Time to Practise - Routing
use instead of because a automatically reloads the page
use NavLink for passing active
key has to go to the top element
to={this,props.url.match}
without switch everything is rendered, which matches
params
queryparams
new URLSearchParams(this.props.location.search) (javascript object) (minute 20)
componentDidUpdate()
208 Routing and Server Deployment
always load index.html also for unknown requests
one has to configure it by oneself
set basename="/my-app" when using suburl
important for subdirectory usage
207 Lazy Loading with React Suspense (16.6)
no need for hoc
always useful in conditional situatioins
React.Fragment --> used to wrap other compoents like aux, does not render real component
use default exports, named exports are not supported
react lazy does not support server side rendering
constPosts=React.lazy(()=>import('./containers/Posts'))<Routepath="/posts"components={Posts}>// need to be changed to <Routepath="/posts"render={()=>(<Suspensefallback={<div>Loading...</div>}><Posts/></Suspense>)}/>// <React.Fragment><button> ...
</React.Fragment>
206 Loading Routes Lazily
codesplitting or lazyloading
create-react-app (modern config) and react-router 4
add hoc/asyncComponent.js
dynamic import()
bundle.js vs 1.chunk.js
205 Handling the 404 Case (Unknown Routes)
redirect or
catch any unknown routes
<Routerender={()=><h1>Not found</h1>}/>// should always come last// wont work in combination with redirect
204 Working with Guards
isAuthenticated is one use case
you control how the components are rendered
203 Using the History Prop to Redirect (Replace)
history exists in every component which is inside Router
// does the same like redirectthis.props.history.push('/posts')// push adds to the history stack, redirect replacesthis.props.history.replace('/posts')// same as redirect
202 Conditional Redirects
201 Redirecting Requests
possible from within switch
<Rediretfrom="/"to"/posts" />
200 Creating Dynamic Nested Routes
use componentDidUpdate to rerender, when nested route is changed
defines that only the first match will be rendered
order is important
can be mixed
195 Parsing Query Parameters & the Fragment
<Linkto="/my-path?start=5">Go to Start</Link>// or<Linkto={{pathname: '/my-path',search: '?start=5'}}>GotoStart</Link>// extractcomponentDidMount(){constquery=newURLSearchParams(this.props.location.search);for(letparamofquery.entries()){console.log(param);// yields ['start', '5']}}// Fragment:// You can pass it easily like this:<Linkto="/my-path#start-position">GotoStart</Link> // or<Linkto={{pathname: '/my-path',hash: 'start-position'}}>GotoStart</Link>// React router makes it easy to extract the fragment. You can simply access props.location.hash .
194 Extracting Route Parameters
this.props.match.params.id
193 Passing Route Parameters
// dynamic route<Routepath="/:id"exactcomponent={FullPost}>
// wrap single post in posts with Link
<Linkto={post.id}key={post.id}>
...
192 Styling the Active Route
NavLink instead of Link
adds class="active"
be aware of exact
// change active class name / active style<NavLinkto="/"exactactiveClassName="my-active"activeStyle={{color: '#fa923f',text-decoration: 'underline'}}>
191 Absolute vs Relative Paths (Article)
Youlearnedabout<Link>,youlearnedaboutthetopropertyituses.Thepathyoucanuseintocanbeeitherabsoluteorrelative.AbsolutePathsBydefault,ifyoujustenterto="/some-path"orto="some-path",that's an absolute path. Absolute path means that it'salwaysappendedrightafteryourdomain.Therefore,bothsyntaxes(withandwithoutleadingslash)leadtoexample.com/some-path.RelativePathsSometimes,youmightwanttocreatearelativepathinstead.Thisisespeciallyuseful,ifyourcomponentisalreadyloadedgivenaspecificpath(e.g.posts)andyouthenwanttoappendsomethingtothatexistingpath(sothatyou,forexample,get/posts/new).Ifyou're on a component loaded via /posts , to="new" would lead to example.com/new , NOT example.com/posts/new . To change this behavior, you have to find out which path you'reonandaddthenewfragmenttothatexistingpath.Youcandothatwiththeurlpropertyofprops.match :
<Linkto={props.match.url+'/new'}>willleadtoexample.com/posts/newwhenplacingthislinkinacomponentloadedon/posts.Ifyou'd use the same <Link> in a component loaded via /all-posts , the link would point to /all-posts/new .There'snobetterorworsewayofcreatingLinkpaths-choosetheoneyouneed.Sometimes,youwanttoensurethatyoualwaysloadthesamepath,nomatteronwhichpathyoualreadyare=>Useabsolutepathsinthisscenario.Userelativepathsifyouwanttonavigaterelativetoyourexistingpath.
you can pass on props manually to child components
match={this.props.match}
hoc withRouter
exportdefaultwithRouter(post);
188 Using Routing-Related Props
React Router enriches the props object with
history,
location
hash: for example to jump to specific location
match
187 Using Links to Switch Pages
with Link it wont reload again
// add the Link component<Linkto="/">Home</Link>// advanced setup<Linkto={{pathname: '/new-post',hash: '#submit',search: '?quick-submit=true'}}">Home</Link>
186 Switching Between Pages
reloading problem
185 Rendering Components for Routes
// comment out jsx{/* */}
<Routepath="/posts"component={Posts}/>
184 Setting Up and Rendering Routes
183 Preparing the Project For Routing
Routeattributes
exact
path
render()
Routes and Links are seperated
182 react-router vs react-router-dom
We installed both react-router and react-router-dom . Technically, only react-router-dom is required for web development. It wraps react-router and therefore uses it as a dependency. We don't need to install react-router on our own for it to work. You can omit this installation step, I left it in there for historic reasons and because I like to emphasize that the main package is named react-router. If you ever search for assistance, you probably want to search for "react router" - that's the name of the package
181 Setting Up the Router Package
react-router logic
react-router-dom visualization
180 Setting Up Links
179 routing and spas
beeing able to show different pages to the user
navigating
use a Router Package
Parses URL / Paths
Read Config
Render / Load appropriate JSX / Component
178 Module Intro
Routing is not build into the core of react
we use a package, which is not build by react but defacto standard
10 Burger Builder Project: Accessing a Server
177 Useful Resources & Links
176 Removing Old Interceptors
175 Retrieving Data from the Backend
174 Handling Errors
withErrorHandler
// starting with lower case, because we are not using it in jsximportwithErrorHandlerfrom('.')exportdefaultwithErrorHandler(BurgerBuilder)// return anonymous classreturnclassextendsComponent{}
importPropTypesfrom'prop-types';MyComponent.propTypes={// You can declare that a prop is a specific JS primitive. By default, these// are all optional.optionalArray: PropTypes.array,optionalBool: PropTypes.bool,optionalFunc: PropTypes.func,optionalNumber: PropTypes.number,optionalObject: PropTypes.object,optionalString: PropTypes.string,optionalSymbol: PropTypes.symbol,// Anything that can be rendered: numbers, strings, elements or an array// (or fragment) containing these types.optionalNode: PropTypes.node,// A React element.optionalElement: PropTypes.element,// You can also declare that a prop is an instance of a class. This uses// JS's instanceof operator.optionalMessage: PropTypes.instanceOf(Message),// You can ensure that your prop is limited to specific values by treating// it as an enum.optionalEnum: PropTypes.oneOf(['News','Photos']),// An object that could be one of many typesoptionalUnion: PropTypes.oneOfType([PropTypes.string,PropTypes.number,PropTypes.instanceOf(Message)]),// An array of a certain typeoptionalArrayOf: PropTypes.arrayOf(PropTypes.number),// An object with property values of a certain typeoptionalObjectOf: PropTypes.objectOf(PropTypes.number),// An object taking on a particular shapeoptionalObjectWithShape: PropTypes.shape({color: PropTypes.string,fontSize: PropTypes.number}),// You can chain any of the above with `isRequired` to make sure a warning// is shown if the prop isn't provided.requiredFunc: PropTypes.func.isRequired,// A value of any data typerequiredAny: PropTypes.any.isRequired,// You can also specify a custom validator. It should return an Error// object if the validation fails. Don't `console.warn` or throw, as this// won't work inside `oneOfType`.customProp: function(props,propName,componentName){if(!/matchme/.test(props[propName])){returnnewError('Invalid prop `'+propName+'` supplied to'+' `'+componentName+'`. Validation failed.');}},// You can also supply a custom validator to `arrayOf` and `objectOf`.// It should return an Error object if the validation fails. The validator// will be called for each key in the array or object. The first two// arguments of the validator are the array or object itself, and the// current item's key.customArrayProp: PropTypes.arrayOf(function(propValue,key,componentName,location,propFullName){if(!/matchme/.test(propValue[key])){returnnewError('Invalid prop `'+propFullName+'` supplied to'+' `'+componentName+'`. Validation failed.');}})};
Requiring Single Child
With PropTypes.element you can specify that only a single child can be passed to a component as children.
importPropTypesfrom'prop-types';classMyComponentextendsReact.Component{render(){// This must be exactly one element or it will warn.constchildren=this.props.children;return(<div>{children}</div>);}}MyComponent.propTypes={children: PropTypes.element.isRequired};
Default Prop Values
You can define default values for your props by assigning to the special defaultProps property:
classGreetingextendsReact.Component{render(){return(<h1>Hello, {this.props.name}</h1>);}}// Specifies the default values for props:Greeting.defaultProps={name: 'Stranger'};// Renders "Hello, Stranger":ReactDOM.render(<Greeting/>,document.getElementById('example'));
The defaultProps will be used to ensure that this.props.name will have a value if it was not specified by the parent component. The propTypes typechecking happens after defaultProps are resolved, so typechecking will also apply to the defaultProps