UNPKG

2.1 kBJavaScriptView Raw
1import React from "react"
2import loader from "./loader"
3import shallowCompare from "shallow-compare"
4
5class EnsureResources extends React.Component {
6 constructor(props) {
7 super()
8 const { location, pageResources } = props
9 this.state = {
10 location: { ...location },
11 pageResources: pageResources || loader.loadPageSync(location.pathname),
12 }
13 }
14
15 static getDerivedStateFromProps({ location }, prevState) {
16 if (prevState.location.href !== location.href) {
17 const pageResources = loader.loadPageSync(location.pathname)
18 return {
19 pageResources,
20 location: { ...location },
21 }
22 }
23
24 return null
25 }
26
27 loadResources(rawPath) {
28 loader.loadPage(rawPath).then(pageResources => {
29 if (pageResources && pageResources.status !== `error`) {
30 this.setState({
31 location: { ...window.location },
32 pageResources,
33 })
34 } else {
35 window.history.replaceState({}, ``, location.href)
36 window.location = rawPath
37 }
38 })
39 }
40
41 shouldComponentUpdate(nextProps, nextState) {
42 // Always return false if we're missing resources.
43 if (!nextState.pageResources) {
44 this.loadResources(nextProps.location.pathname)
45 return false
46 }
47
48 // Check if the component or json have changed.
49 if (this.state.pageResources !== nextState.pageResources) {
50 return true
51 }
52 if (
53 this.state.pageResources.component !== nextState.pageResources.component
54 ) {
55 return true
56 }
57
58 if (this.state.pageResources.json !== nextState.pageResources.json) {
59 return true
60 }
61 // Check if location has changed on a page using internal routing
62 // via matchPath configuration.
63 if (
64 this.state.location.key !== nextState.location.key &&
65 nextState.pageResources.page &&
66 (nextState.pageResources.page.matchPath ||
67 nextState.pageResources.page.path)
68 ) {
69 return true
70 }
71 return shallowCompare(this, nextProps, nextState)
72 }
73
74 render() {
75 return this.props.children(this.state)
76 }
77}
78
79export default EnsureResources