2
2
* Copyright (c) 2013-present, Facebook, Inc.
3
3
*
4
4
* @emails react-core
5
+ * @flow
5
6
*/
6
7
7
8
'use strict' ;
8
9
9
- import React , { Component } from 'react' ;
10
- import PropTypes from 'prop-types' ;
10
+ import React from 'react' ;
11
11
12
- function replaceArgs ( msg , argList ) {
12
+ import type { Node } from 'react' ;
13
+
14
+ function replaceArgs ( msg : string , argList : Array < string > ) : string {
13
15
let argIdx = 0 ;
14
16
return msg . replace ( / % s / g, function ( ) {
15
17
const arg = argList [ argIdx ++ ] ;
16
18
return arg === undefined ? '[missing argument]' : arg ;
17
19
} ) ;
18
20
}
19
21
20
- function urlify ( str ) {
22
+ // When the message contains a URL (like https://fb.me/react-refs-must-have-owner),
23
+ // make it a clickable link.
24
+ function urlify ( str : string ) : Node {
21
25
const urlRegex = / ( h t t p s : \/ \/ f b \. m e \/ [ a - z \- ] + ) / g;
22
26
23
27
const segments = str . split ( urlRegex ) ;
24
28
25
- for ( let i = 0 ; i < segments . length ; i ++ ) {
29
+ return segments . map ( ( message , i ) => {
26
30
if ( i % 2 === 1 ) {
27
- segments [ i ] = (
28
- < a key = { i } target = "_blank" rel = "noopener" href = { segments [ i ] } >
29
- { segments [ i ] }
31
+ return (
32
+ < a key = { i } target = "_blank" rel = "noopener" href = { message } >
33
+ { message }
30
34
</ a >
31
35
) ;
32
36
}
33
- }
34
-
35
- return segments ;
37
+ return message ;
38
+ } ) ;
36
39
}
37
40
38
- // ?invariant=123&args[]=foo&args[]=bar
39
- function parseQueryString ( location ) {
40
- const rawQueryString = location . search . substring ( 1 ) ;
41
+ // `?invariant=123&args[]=foo&args[]=bar`
42
+ // or `// ?invariant=123&args[0]=foo&args[1]=bar`
43
+ function parseQueryString (
44
+ search : string ,
45
+ ) : ?{ | code : string , args : Array < string > | } {
46
+ const rawQueryString = search . substring ( 1 ) ;
41
47
if ( ! rawQueryString ) {
42
48
return null ;
43
49
}
@@ -50,15 +56,15 @@ function parseQueryString(location) {
50
56
const query = decodeURIComponent ( queries [ i ] ) ;
51
57
if ( query . indexOf ( 'invariant=' ) === 0 ) {
52
58
code = query . slice ( 10 ) ;
53
- } else if ( query . indexOf ( 'args[]= ' ) === 0 ) {
54
- args . push ( query . slice ( 7 ) ) ;
59
+ } else if ( query . indexOf ( 'args[' ) === 0 ) {
60
+ args . push ( query . slice ( query . indexOf ( ']=' ) + 2 ) ) ;
55
61
}
56
62
}
57
63
58
- return [ code , args ] ;
64
+ return { args , code } ;
59
65
}
60
66
61
- function ErrorResult ( props ) {
67
+ function ErrorResult ( props : { | code : ? string , msg : string | } ) {
62
68
const code = props . code ;
63
69
const errorMsg = props . msg ;
64
70
@@ -79,39 +85,21 @@ function ErrorResult(props) {
79
85
) ;
80
86
}
81
87
82
- class ErrorDecoder extends Component {
83
- constructor ( ...args ) {
84
- super ( ...args ) ;
85
-
86
- this . state = {
87
- code : null ,
88
- errorMsg : '' ,
89
- } ;
88
+ function ErrorDecoder ( props : { |
89
+ errorCodesString : string ,
90
+ location : { search : string } ,
91
+ | } ) {
92
+ let code = null ;
93
+ let msg = '';
94
+
95
+ const errorCodes = JSON . parse ( props . errorCodesString ) ;
96
+ const parseResult = parseQueryString ( props . location . search ) ;
97
+ if ( parseResult != null ) {
98
+ code = parseResult . code ;
99
+ msg = replaceArgs ( errorCodes [ code ] , parseResult . args ) ;
90
100
}
91
101
92
- componentWillMount ( ) {
93
- const { errorCodesString} = this . props ;
94
- const errorCodes = JSON . parse ( errorCodesString ) ;
95
- const parseResult = parseQueryString ( this . props . location ) ;
96
- if ( parseResult != null ) {
97
- const [ code , args ] = parseResult ;
98
- if ( errorCodes [ code ] ) {
99
- this . setState ( {
100
- code : code ,
101
- errorMsg : replaceArgs ( errorCodes [ code ] , args ) ,
102
- } ) ;
103
- }
104
- }
105
- }
106
-
107
- render ( ) {
108
- return < ErrorResult code = { this . state . code } msg = { this . state . errorMsg } /> ;
109
- }
102
+ return < ErrorResult code = { code} msg = { msg} / > ;
110
103
}
111
104
112
- ErrorDecoder . propTypes = {
113
- errorCodesString : PropTypes . string . isRequired ,
114
- location : PropTypes . object . isRequired ,
115
- } ;
116
-
117
105
export default ErrorDecoder ;
0 commit comments