UNPKG

2.14 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 {
25 location: { ...location },
26 }
27 }
28
29 loadResources(rawPath) {
30 loader.loadPage(rawPath).then(pageResources => {
31 if (pageResources && pageResources.status !== `error`) {
32 this.setState({
33 location: { ...window.location },
34 pageResources,
35 })
36 } else {
37 window.history.replaceState({}, ``, location.href)
38 window.location = rawPath
39 }
40 })
41 }
42
43 shouldComponentUpdate(nextProps, nextState) {
44 // Always return false if we're missing resources.
45 if (!nextState.pageResources) {
46 this.loadResources(nextProps.location.pathname)
47 return false
48 }
49
50 // Check if the component or json have changed.
51 if (this.state.pageResources !== nextState.pageResources) {
52 return true
53 }
54 if (
55 this.state.pageResources.component !== nextState.pageResources.component
56 ) {
57 return true
58 }
59
60 if (this.state.pageResources.json !== nextState.pageResources.json) {
61 return true
62 }
63 // Check if location has changed on a page using internal routing
64 // via matchPath configuration.
65 if (
66 this.state.location.key !== nextState.location.key &&
67 nextState.pageResources.page &&
68 (nextState.pageResources.page.matchPath ||
69 nextState.pageResources.page.path)
70 ) {
71 return true
72 }
73 return shallowCompare(this, nextProps, nextState)
74 }
75
76 render() {
77 return this.props.children(this.state)
78 }
79}
80
81export default EnsureResources