@@ -24,31 +24,51 @@ class Media extends React.Component {
2424
2525 queries = [ ] ;
2626
27- state = {
28- matches :
29- this . props . defaultMatches ||
30- Object . keys ( this . props . queries ) . reduce (
31- ( acc , key ) => ( { ...acc , [ key ] : true } ) ,
32- { }
33- )
34- } ;
27+ constructor ( props ) {
28+ super ( props ) ;
29+
30+ if ( typeof window !== "object" ) {
31+ // In case we're rendering on the server
32+ this . state = {
33+ matches :
34+ this . props . defaultMatches ||
35+ Object . keys ( this . props . queries ) . reduce (
36+ ( acc , key ) => ( { ...acc , [ key ] : true } ) ,
37+ { }
38+ )
39+ } ;
40+ return ;
41+ }
3542
36- updateMatches = ( ) => {
37- const newMatches = this . queries . reduce (
43+ this . initialize ( ) ;
44+
45+ // Instead of calling this.updateMatches, we manually set the state to prevent
46+ // calling setState, which could trigger an unnecessary second render
47+ this . state = {
48+ matches :
49+ this . props . defaultMatches !== undefined
50+ ? this . props . defaultMatches
51+ : this . getMatches ( )
52+ } ;
53+ this . onChange ( ) ;
54+ }
55+
56+ getMatches = ( ) => {
57+ return this . queries . reduce (
3858 ( acc , { name, mqList } ) => ( { ...acc , [ name ] : mqList . matches } ) ,
3959 { }
4060 ) ;
41- this . setState ( { matches : newMatches } ) ;
42-
43- const { onChange } = this . props ;
44- if ( onChange ) {
45- onChange ( newMatches ) ;
46- }
4761 } ;
4862
49- componentWillMount ( ) {
50- if ( typeof window !== "object" ) return ;
63+ updateMatches = ( ) => {
64+ const newMatches = this . getMatches ( ) ;
5165
66+ this . setState ( ( ) => ( {
67+ matches : newMatches
68+ } ) , this . onChange ) ;
69+ } ;
70+
71+ initialize ( ) {
5272 const targetWindow = this . props . targetWindow || window ;
5373
5474 invariant (
@@ -67,8 +87,23 @@ class Media extends React.Component {
6787
6888 return { name, qs, mqList } ;
6989 } ) ;
90+ }
7091
71- this . updateMatches ( ) ;
92+ componentDidMount ( ) {
93+ this . initialize ( ) ;
94+ // If props.defaultMatches has been set, ensure we trigger a two-pass render.
95+ // This is useful for SSR with mismatching defaultMatches vs actual matches from window.matchMedia
96+ // Details: https://github.com/ReactTraining/react-media/issues/81
97+ if ( this . props . defaultMatches !== undefined ) {
98+ this . updateMatches ( ) ;
99+ }
100+ }
101+
102+ onChange ( ) {
103+ const { onChange } = this . props ;
104+ if ( onChange ) {
105+ onChange ( this . state . matches ) ;
106+ }
72107 }
73108
74109 componentWillUnmount ( ) {
0 commit comments