1
1
import PropTypes from 'prop-types' ;
2
- import React from 'react' ;
3
- import { connect } from 'react-redux' ;
4
- import { withRouter } from 'react-router-dom' ;
2
+ import React , { useEffect , useRef , useState } from 'react' ;
3
+ import { useDispatch , useSelector } from 'react-redux' ;
4
+ import { useLocation } from 'react-router-dom' ;
5
5
import getConfig from '../../utils/getConfig' ;
6
6
import DevTools from './components/DevTools' ;
7
7
import { setPreviousPath } from '../IDE/actions/ide' ;
@@ -15,77 +15,57 @@ function hideCookieConsent(pathname) {
15
15
return false ;
16
16
}
17
17
18
- class App extends React . Component {
19
- constructor ( props , context ) {
20
- super ( props , context ) ;
21
- this . state = { isMounted : false } ;
22
- }
18
+ const App = ( { children } ) => {
19
+ const dispatch = useDispatch ( ) ;
23
20
24
- componentDidMount ( ) {
25
- this . setState ( { isMounted : true } ) ; // eslint-disable-line react/no-did-mount-set-state
26
- document . body . className = this . props . theme ;
27
- }
21
+ const location = useLocation ( ) ;
28
22
29
- componentWillReceiveProps ( nextProps ) {
30
- const locationWillChange = nextProps . location !== this . props . location ;
31
- const shouldSkipRemembering =
32
- nextProps . location . state &&
33
- nextProps . location . state . skipSavingPath === true ;
23
+ const theme = useSelector ( ( state ) => state . preferences . theme ) ;
24
+ useEffect ( ( ) => {
25
+ document . body . className = theme ;
26
+ } , [ theme ] ) ;
34
27
35
- if ( locationWillChange && ! shouldSkipRemembering ) {
36
- this . props . setPreviousPath ( this . props . location . pathname ) ;
37
- }
28
+ // TODO: this is only needed for the initial load and would be better handled elsewhere - Linda
29
+ const language = useSelector ( ( state ) => state . preferences . language ) ;
30
+ useEffect ( ( ) => {
31
+ dispatch ( setLanguage ( language , { persistPreference : false } ) ) ;
32
+ } , [ language ] ) ;
38
33
39
- if ( this . props . language !== nextProps . language ) {
40
- this . props . setLanguage ( nextProps . language , { persistPreference : false } ) ;
41
- }
42
- }
34
+ // TODO: do we actually need this? - Linda
35
+ const [ isMounted , setIsMounted ] = useState ( false ) ;
36
+ useEffect ( ( ) => setIsMounted ( true ) , [ ] ) ;
37
+
38
+ const previousLocationRef = useRef ( location ) ;
39
+ useEffect ( ( ) => {
40
+ const prevLocation = previousLocationRef . current ;
41
+ const locationChanged = prevLocation && prevLocation !== location ;
42
+ const shouldSkipRemembering = location . state ?. skipSavingPath === true ;
43
43
44
- componentDidUpdate ( prevProps ) {
45
- if ( this . props . theme !== prevProps . theme ) {
46
- document . body . className = this . props . theme ;
44
+ if ( locationChanged && ! shouldSkipRemembering ) {
45
+ dispatch ( setPreviousPath ( prevLocation . pathname ) ) ;
47
46
}
48
- }
47
+ previousLocationRef . current = location ;
48
+ } , [ location ] ) ;
49
49
50
- render ( ) {
51
- const hide = hideCookieConsent ( this . props . location . pathname ) ;
52
- return (
53
- < div className = "app" >
54
- < CookieConsent hide = { hide } />
55
- { this . state . isMounted &&
56
- ! window . devToolsExtension &&
57
- getConfig ( 'NODE_ENV' ) === 'development' && < DevTools /> }
58
- { this . props . children }
59
- </ div >
60
- ) ;
61
- }
62
- }
50
+ const hide = hideCookieConsent ( location . pathname ) ;
51
+
52
+ return (
53
+ < div className = "app" >
54
+ < CookieConsent hide = { hide } />
55
+ { isMounted &&
56
+ ! window . devToolsExtension &&
57
+ getConfig ( 'NODE_ENV' ) === 'development' && < DevTools /> }
58
+ { children }
59
+ </ div >
60
+ ) ;
61
+ } ;
63
62
64
63
App . propTypes = {
65
- children : PropTypes . element ,
66
- location : PropTypes . shape ( {
67
- pathname : PropTypes . string ,
68
- state : PropTypes . shape ( {
69
- skipSavingPath : PropTypes . bool
70
- } )
71
- } ) . isRequired ,
72
- setPreviousPath : PropTypes . func . isRequired ,
73
- setLanguage : PropTypes . func . isRequired ,
74
- language : PropTypes . string ,
75
- theme : PropTypes . string
64
+ children : PropTypes . element
76
65
} ;
77
66
78
67
App . defaultProps = {
79
- children : null ,
80
- language : null ,
81
- theme : 'light'
68
+ children : null
82
69
} ;
83
70
84
- const mapStateToProps = ( state ) => ( {
85
- theme : state . preferences . theme ,
86
- language : state . preferences . language
87
- } ) ;
88
-
89
- const mapDispatchToProps = { setPreviousPath, setLanguage } ;
90
-
91
- export default withRouter ( connect ( mapStateToProps , mapDispatchToProps ) ( App ) ) ;
71
+ export default App ;
0 commit comments