-
Notifications
You must be signed in to change notification settings - Fork 6
/
react-native.html
1192 lines (1085 loc) · 69.7 KB
/
react-native.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html><html><head><meta charset="utf-8"><style>html { font-size: 100%; overflow-y: scroll; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
body{
color:#444;
font-family:Georgia, Palatino, 'Palatino Linotype', Times, 'Times New Roman',
"Hiragino Sans GB", "STXihei", "微软雅黑", serif;
font-size:12px;
line-height:1.5em;
background:#fefefe;
width: 45em;
margin: 10px auto;
padding: 1em;
outline: 1300px solid #FAFAFA;
}
a{ color: #0645ad; text-decoration:none;}
a:visited{ color: #0b0080; }
a:hover{ color: #06e; }
a:active{ color:#faa700; }
a:focus{ outline: thin dotted; }
a:hover, a:active{ outline: 0; }
span.backtick {
border:1px solid #EAEAEA;
border-radius:3px;
background:#F8F8F8;
padding:0 3px 0 3px;
}
::-moz-selection{background:rgba(255,255,0,0.3);color:#000}
::selection{background:rgba(255,255,0,0.3);color:#000}
a::-moz-selection{background:rgba(255,255,0,0.3);color:#0645ad}
a::selection{background:rgba(255,255,0,0.3);color:#0645ad}
p{
margin:1em 0;
}
img{
max-width:100%;
}
h1,h2,h3,h4,h5,h6{
font-weight:normal;
color:#111;
line-height:1em;
}
h4,h5,h6{ font-weight: bold; }
h1{ font-size:2.5em; }
h2{ font-size:2em; border-bottom:1px solid silver; padding-bottom: 5px; }
h3{ font-size:1.5em; }
h4{ font-size:1.2em; }
h5{ font-size:1em; }
h6{ font-size:0.9em; }
blockquote{
color:#666666;
margin:0;
padding-left: 3em;
border-left: 0.5em #EEE solid;
}
hr { display: block; height: 2px; border: 0; border-top: 1px solid #aaa;border-bottom: 1px solid #eee; margin: 1em 0; padding: 0; }
pre , code, kbd, samp {
color: #000;
font-family: monospace;
font-size: 0.88em;
border-radius:3px;
background-color: #F8F8F8;
border: 1px solid #CCC;
}
pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; padding: 5px 12px;}
pre code { border: 0px !important; padding: 0;}
code { padding: 0 3px 0 3px; }
b, strong { font-weight: bold; }
dfn { font-style: italic; }
ins { background: #ff9; color: #000; text-decoration: none; }
mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }
sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
sup { top: -0.5em; }
sub { bottom: -0.25em; }
ul, ol { margin: 1em 0; padding: 0 0 0 2em; }
li p:last-child { margin:0 }
dd { margin: 0 0 0 2em; }
img { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; }
table { border-collapse: collapse; border-spacing: 0; }
td { vertical-align: top; }
@media only screen and (min-width: 480px) {
body{font-size:14px;}
}
@media only screen and (min-width: 768px) {
body{font-size:16px;}
}
@media print {
* { background: transparent !important; color: black !important; filter:none !important; -ms-filter: none !important; }
body{font-size:12pt; max-width:100%; outline:none;}
a, a:visited { text-decoration: underline; }
hr { height: 1px; border:0; border-bottom:1px solid black; }
a[href]:after { content: " (" attr(href) ")"; }
abbr[title]:after { content: " (" attr(title) ")"; }
.ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; }
pre, blockquote { border: 1px solid #999; padding-right: 1em; page-break-inside: avoid; }
tr, img { page-break-inside: avoid; }
img { max-width: 100% !important; }
@page :left { margin: 15mm 20mm 15mm 10mm; }
@page :right { margin: 15mm 10mm 15mm 20mm; }
p, h2, h3 { orphans: 3; widows: 3; }
h2, h3 { page-break-after: avoid; }
}
</style><style>/* to allow side-by-side code blocks */
.join {
height: 0;
margin: 0;
}
.join + pre {
width: 45%;
float:left;
display: inline-block;
margin-top: 0;
margin-bottom: 0;
}
pre + pre {
display: inline-block;
width: 45%;
float: right;
margin-top: 0;
margin-bottom: 0;
}
pre + .clear {
margin: 0;
height: 0;
clear: both;
}
ul ul {
margin-top: 0;
margin-bottom: 0;
}
/* Fork me on Github*/
img.github {
position: absolute;
top: 0;
right: 0;
border: 0;
}
/* headers and top links*/
#top {
position: absolute;
top:0;
}
.top {
float:right;
padding-top: 20px;
}
/* "Responsive" */
body {
width: 90%;
max-width: 50em;
}
/* make tables pretty */
table {
padding: 0;border-collapse: collapse; }
table tr {
border-top: 1px solid #cccccc;
background-color: white;
margin: 0;
padding: 0; }
table tr:nth-child(2n) {
background-color: #f8f8f8; }
table tr th {
font-weight: bold;
border: 1px solid #cccccc;
border-bottom-width: 3px;
margin: 0;
padding: 6px 13px; }
table tr td {
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }
table tr th :first-child, table tr td :first-child {
margin-top: 0; }
table tr th :last-child, table tr td :last-child {
margin-bottom: 0; }</style><style>/*
github.com style (c) Vasily Polovnyov <[email protected]>
*/
pre code {
display: block; padding: 0.5em;
color: #333;
background: #f8f8ff
}
pre .comment,
pre .template_comment,
pre .diff .header,
pre .javadoc {
color: #998;
font-style: italic
}
pre .keyword,
pre .css .rule .keyword,
pre .winutils,
pre .javascript .title,
pre .nginx .title,
pre .subst,
pre .request,
pre .status {
color: #333;
font-weight: bold
}
pre .number,
pre .hexcolor,
pre .ruby .constant {
color: #099;
}
pre .string,
pre .tag .value,
pre .phpdoc,
pre .tex .formula {
color: #d14
}
pre .title,
pre .id,
pre .coffeescript .params,
pre .scss .preprocessor {
color: #900;
font-weight: bold
}
pre .javascript .title,
pre .lisp .title,
pre .clojure .title,
pre .subst {
font-weight: normal
}
pre .class .title,
pre .haskell .type,
pre .vhdl .literal,
pre .tex .command {
color: #458;
font-weight: bold
}
pre .tag,
pre .tag .title,
pre .rules .property,
pre .django .tag .keyword {
color: #000080;
font-weight: normal
}
pre .attribute,
pre .variable,
pre .lisp .body {
color: #008080
}
pre .regexp {
color: #009926
}
pre .class {
color: #458;
font-weight: bold
}
pre .symbol,
pre .ruby .symbol .string,
pre .lisp .keyword,
pre .tex .special,
pre .prompt {
color: #990073
}
pre .built_in,
pre .lisp .title,
pre .clojure .built_in {
color: #0086b3
}
pre .preprocessor,
pre .pi,
pre .doctype,
pre .shebang,
pre .cdata {
color: #999;
font-weight: bold
}
pre .deletion {
background: #fdd
}
pre .addition {
background: #dfd
}
pre .diff .change {
background: #0086b3
}
pre .chunk {
color: #aaa
}</style><script>var hljs=new function(){function l(o){return o.replace(/&/gm,"&").replace(/</gm,"<").replace(/>/gm,">")}function b(p){for(var o=p.firstChild;o;o=o.nextSibling){if(o.nodeName=="CODE"){return o}if(!(o.nodeType==3&&o.nodeValue.match(/\s+/))){break}}}function h(p,o){return Array.prototype.map.call(p.childNodes,function(q){if(q.nodeType==3){return o?q.nodeValue.replace(/\n/g,""):q.nodeValue}if(q.nodeName=="BR"){return"\n"}return h(q,o)}).join("")}function a(q){var p=(q.className+" "+q.parentNode.className).split(/\s+/);p=p.map(function(r){return r.replace(/^language-/,"")});for(var o=0;o<p.length;o++){if(e[p[o]]||p[o]=="no-highlight"){return p[o]}}}function c(q){var o=[];(function p(r,s){for(var t=r.firstChild;t;t=t.nextSibling){if(t.nodeType==3){s+=t.nodeValue.length}else{if(t.nodeName=="BR"){s+=1}else{if(t.nodeType==1){o.push({event:"start",offset:s,node:t});s=p(t,s);o.push({event:"stop",offset:s,node:t})}}}}return s})(q,0);return o}function j(x,v,w){var p=0;var y="";var r=[];function t(){if(x.length&&v.length){if(x[0].offset!=v[0].offset){return(x[0].offset<v[0].offset)?x:v}else{return v[0].event=="start"?x:v}}else{return x.length?x:v}}function s(A){function z(B){return" "+B.nodeName+'="'+l(B.value)+'"'}return"<"+A.nodeName+Array.prototype.map.call(A.attributes,z).join("")+">"}while(x.length||v.length){var u=t().splice(0,1)[0];y+=l(w.substr(p,u.offset-p));p=u.offset;if(u.event=="start"){y+=s(u.node);r.push(u.node)}else{if(u.event=="stop"){var o,q=r.length;do{q--;o=r[q];y+=("</"+o.nodeName.toLowerCase()+">")}while(o!=u.node);r.splice(q,1);while(q<r.length){y+=s(r[q]);q++}}}}return y+l(w.substr(p))}function f(q){function o(s,r){return RegExp(s,"m"+(q.cI?"i":"")+(r?"g":""))}function p(y,w){if(y.compiled){return}y.compiled=true;var s=[];if(y.k){var r={};function z(A,t){t.split(" ").forEach(function(B){var C=B.split("|");r[C[0]]=[A,C[1]?Number(C[1]):1];s.push(C[0])})}y.lR=o(y.l||hljs.IR,true);if(typeof y.k=="string"){z("keyword",y.k)}else{for(var x in y.k){if(!y.k.hasOwnProperty(x)){continue}z(x,y.k[x])}}y.k=r}if(w){if(y.bWK){y.b="\\b("+s.join("|")+")\\s"}y.bR=o(y.b?y.b:"\\B|\\b");if(!y.e&&!y.eW){y.e="\\B|\\b"}if(y.e){y.eR=o(y.e)}y.tE=y.e||"";if(y.eW&&w.tE){y.tE+=(y.e?"|":"")+w.tE}}if(y.i){y.iR=o(y.i)}if(y.r===undefined){y.r=1}if(!y.c){y.c=[]}for(var v=0;v<y.c.length;v++){if(y.c[v]=="self"){y.c[v]=y}p(y.c[v],y)}if(y.starts){p(y.starts,w)}var u=[];for(var v=0;v<y.c.length;v++){u.push(y.c[v].b)}if(y.tE){u.push(y.tE)}if(y.i){u.push(y.i)}y.t=u.length?o(u.join("|"),true):{exec:function(t){return null}}}p(q)}function d(D,E){function o(r,M){for(var L=0;L<M.c.length;L++){var K=M.c[L].bR.exec(r);if(K&&K.index==0){return M.c[L]}}}function s(K,r){if(K.e&&K.eR.test(r)){return K}if(K.eW){return s(K.parent,r)}}function t(r,K){return K.i&&K.iR.test(r)}function y(L,r){var K=F.cI?r[0].toLowerCase():r[0];return L.k.hasOwnProperty(K)&&L.k[K]}function G(){var K=l(w);if(!A.k){return K}var r="";var N=0;A.lR.lastIndex=0;var L=A.lR.exec(K);while(L){r+=K.substr(N,L.index-N);var M=y(A,L);if(M){v+=M[1];r+='<span class="'+M[0]+'">'+L[0]+"</span>"}else{r+=L[0]}N=A.lR.lastIndex;L=A.lR.exec(K)}return r+K.substr(N)}function z(){if(A.sL&&!e[A.sL]){return l(w)}var r=A.sL?d(A.sL,w):g(w);if(A.r>0){v+=r.keyword_count;B+=r.r}return'<span class="'+r.language+'">'+r.value+"</span>"}function J(){return A.sL!==undefined?z():G()}function I(L,r){var K=L.cN?'<span class="'+L.cN+'">':"";if(L.rB){x+=K;w=""}else{if(L.eB){x+=l(r)+K;w=""}else{x+=K;w=r}}A=Object.create(L,{parent:{value:A}});B+=L.r}function C(K,r){w+=K;if(r===undefined){x+=J();return 0}var L=o(r,A);if(L){x+=J();I(L,r);return L.rB?0:r.length}var M=s(A,r);if(M){if(!(M.rE||M.eE)){w+=r}x+=J();do{if(A.cN){x+="</span>"}A=A.parent}while(A!=M.parent);if(M.eE){x+=l(r)}w="";if(M.starts){I(M.starts,"")}return M.rE?0:r.length}if(t(r,A)){throw"Illegal"}w+=r;return r.length||1}var F=e[D];f(F);var A=F;var w="";var B=0;var v=0;var x="";try{var u,q,p=0;while(true){A.t.lastIndex=p;u=A.t.exec(E);if(!u){break}q=C(E.substr(p,u.index-p),u[0]);p=u.index+q}C(E.substr(p));return{r:B,keyword_count:v,value:x,language:D}}catch(H){if(H=="Illegal"){return{r:0,keyword_count:0,value:l(E)}}else{throw H}}}function g(s){var o={keyword_count:0,r:0,value:l(s)};var q=o;for(var p in e){if(!e.hasOwnProperty(p)){continue}var r=d(p,s);r.language=p;if(r.keyword_count+r.r>q.keyword_count+q.r){q=r}if(r.keyword_count+r.r>o.keyword_count+o.r){q=o;o=r}}if(q.language){o.second_best=q}return o}function i(q,p,o){if(p){q=q.replace(/^((<[^>]+>|\t)+)/gm,function(r,v,u,t){return v.replace(/\t/g,p)})}if(o){q=q.replace(/\n/g,"<br>")}return q}function m(r,u,p){var v=h(r,p);var t=a(r);if(t=="no-highlight"){return}var w=t?d(t,v):g(v);t=w.language;var o=c(r);if(o.length){var q=document.createElement("pre");q.innerHTML=w.value;w.value=j(o,c(q),v)}w.value=i(w.value,u,p);var s=r.className;if(!s.match("(\\s|^)(language-)?"+t+"(\\s|$)")){s=s?(s+" "+t):t}r.innerHTML=w.value;r.className=s;r.result={language:t,kw:w.keyword_count,re:w.r};if(w.second_best){r.second_best={language:w.second_best.language,kw:w.second_best.keyword_count,re:w.second_best.r}}}function n(){if(n.called){return}n.called=true;Array.prototype.map.call(document.getElementsByTagName("pre"),b).filter(Boolean).forEach(function(o){m(o,hljs.tabReplace)})}function k(){window.addEventListener("DOMContentLoaded",n,false);window.addEventListener("load",n,false)}var e={};this.LANGUAGES=e;this.highlight=d;this.highlightAuto=g;this.fixMarkup=i;this.highlightBlock=m;this.initHighlighting=n;this.initHighlightingOnLoad=k;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.inherit=function(q,r){var o={};for(var p in q){o[p]=q[p]}if(r){for(var p in r){o[p]=r[p]}}return o}}();hljs.LANGUAGES.bash=function(a){var g="true false";var e="if then else elif fi for break continue while in do done echo exit return set declare";var c={cN:"variable",b:"\\$[a-zA-Z0-9_#]+"};var b={cN:"variable",b:"\\${([^}]|\\\\})+}"};var h={cN:"string",b:'"',e:'"',i:"\\n",c:[a.BE,c,b],r:0};var d={cN:"string",b:"'",e:"'",c:[{b:"''"}],r:0};var f={cN:"test_condition",b:"",e:"",c:[h,d,c,b],k:{literal:g},r:0};return{k:{keyword:e,literal:g},c:[{cN:"shebang",b:"(#!\\/bin\\/bash)|(#!\\/bin\\/sh)",r:10},c,b,a.HCM,h,d,a.inherit(f,{b:"\\[ ",e:" \\]",r:0}),a.inherit(f,{b:"\\[\\[ ",e:" \\]\\]"})]}}(hljs);hljs.LANGUAGES.cs=function(a){return{k:"abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while ascending descending from get group into join let orderby partial select set value var where yield",c:[{cN:"comment",b:"///",e:"$",rB:true,c:[{cN:"xmlDocTag",b:"///|<!--|-->"},{cN:"xmlDocTag",b:"</?",e:">"}]},a.CLCM,a.CBLCLM,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line region endregion pragma checksum"},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},a.ASM,a.QSM,a.CNM]}}(hljs);hljs.LANGUAGES.ruby=function(e){var a="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var j="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var g={keyword:"and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include"};var c={cN:"yardoctag",b:"@[A-Za-z]+"};var k=[{cN:"comment",b:"#",e:"$",c:[c]},{cN:"comment",b:"^\\=begin",e:"^\\=end",c:[c],r:10},{cN:"comment",b:"^__END__",e:"\\n$"}];var d={cN:"subst",b:"#\\{",e:"}",l:a,k:g};var i=[e.BE,d];var b=[{cN:"string",b:"'",e:"'",c:i,r:0},{cN:"string",b:'"',e:'"',c:i,r:0},{cN:"string",b:"%[qw]?\\(",e:"\\)",c:i},{cN:"string",b:"%[qw]?\\[",e:"\\]",c:i},{cN:"string",b:"%[qw]?{",e:"}",c:i},{cN:"string",b:"%[qw]?<",e:">",c:i,r:10},{cN:"string",b:"%[qw]?/",e:"/",c:i,r:10},{cN:"string",b:"%[qw]?%",e:"%",c:i,r:10},{cN:"string",b:"%[qw]?-",e:"-",c:i,r:10},{cN:"string",b:"%[qw]?\\|",e:"\\|",c:i,r:10}];var h={cN:"function",bWK:true,e:" |$|;",k:"def",c:[{cN:"title",b:j,l:a,k:g},{cN:"params",b:"\\(",e:"\\)",l:a,k:g}].concat(k)};var f=k.concat(b.concat([{cN:"class",bWK:true,e:"$|;",k:"class module",c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]}].concat(k)},h,{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:b.concat([{b:j}]),r:0},{cN:"symbol",b:a+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"number",b:"\\?\\w"},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:k.concat([{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[e.BE,d]}]),r:0}]));d.c=f;h.c[1].c=f;return{l:a,k:g,c:f}}(hljs);hljs.LANGUAGES.diff=function(a){return{c:[{cN:"chunk",b:"^\\@\\@ +\\-\\d+,\\d+ +\\+\\d+,\\d+ +\\@\\@$",r:10},{cN:"chunk",b:"^\\*\\*\\* +\\d+,\\d+ +\\*\\*\\*\\*$",r:10},{cN:"chunk",b:"^\\-\\-\\- +\\d+,\\d+ +\\-\\-\\-\\-$",r:10},{cN:"header",b:"Index: ",e:"$"},{cN:"header",b:"=====",e:"=====$"},{cN:"header",b:"^\\-\\-\\-",e:"$"},{cN:"header",b:"^\\*{3} ",e:"$"},{cN:"header",b:"^\\+\\+\\+",e:"$"},{cN:"header",b:"\\*{5}",e:"\\*{5}$"},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}}(hljs);hljs.LANGUAGES.javascript=function(a){return{k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const",literal:"true false null undefined NaN Infinity"},c:[a.ASM,a.QSM,a.CLCM,a.CBLCLM,a.CNM,{b:"("+a.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[a.CLCM,a.CBLCLM,{cN:"regexp",b:"/",e:"/[gim]*",i:"\\n",c:[{b:"\\\\/"}]},{b:"<",e:">;",sL:"xml"}],r:0},{cN:"function",bWK:true,e:"{",k:"function",c:[{cN:"title",b:"[A-Za-z$_][0-9A-Za-z$_]*"},{cN:"params",b:"\\(",e:"\\)",c:[a.CLCM,a.CBLCLM],i:"[\"'\\(]"}],i:"\\[|%"}]}}(hljs);hljs.LANGUAGES.css=function(a){var b={cN:"function",b:a.IR+"\\(",e:"\\)",c:[a.NM,a.ASM,a.QSM]};return{cI:true,i:"[=/|']",c:[a.CBLCLM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",eE:true,k:"import page media charset",c:[b,a.ASM,a.QSM,a.NM]},{cN:"tag",b:a.IR,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[a.CBLCLM,{cN:"rule",b:"[^\\s]",rB:true,e:";",eW:true,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[b,a.NM,a.QSM,a.ASM,a.CBLCLM,{cN:"hexcolor",b:"\\#[0-9A-F]+"},{cN:"important",b:"!important"}]}}]}]}]}}(hljs);hljs.LANGUAGES.xml=function(a){var c="[A-Za-z0-9\\._:-]+";var b={eW:true,c:[{cN:"attribute",b:c,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[b],starts:{e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},{cN:"tag",b:"</?",e:"/?>",c:[{cN:"title",b:"[^ />]+"},b]}]}}(hljs);hljs.LANGUAGES.http=function(a){return{i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:true,e:"$",c:[{cN:"string",b:" ",e:" ",eB:true,eE:true}]},{cN:"attribute",b:"^\\w",e:": ",eE:true,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:"",eW:true}}]}}(hljs);hljs.LANGUAGES.java=function(a){return{k:"false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws",c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"@[A-Za-z]+"}],r:10},a.CLCM,a.CBLCLM,a.ASM,a.QSM,{cN:"class",bWK:true,e:"{",k:"class interface",i:":",c:[{bWK:true,k:"extends implements",r:10},{cN:"title",b:a.UIR}]},a.CNM,{cN:"annotation",b:"@[A-Za-z]+"}]}}(hljs);hljs.LANGUAGES.php=function(a){var e={cN:"variable",b:"\\$+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"};var b=[a.inherit(a.ASM,{i:null}),a.inherit(a.QSM,{i:null}),{cN:"string",b:'b"',e:'"',c:[a.BE]},{cN:"string",b:"b'",e:"'",c:[a.BE]}];var c=[a.BNM,a.CNM];var d={cN:"title",b:a.UIR};return{cI:true,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return implements parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception php_user_filter default die require __FUNCTION__ enddeclare final try this switch continue endfor endif declare unset true false namespace trait goto instanceof insteadof __DIR__ __NAMESPACE__ __halt_compiler",c:[a.CLCM,a.HCM,{cN:"comment",b:"/\\*",e:"\\*/",c:[{cN:"phpdoc",b:"\\s@[A-Za-z]+"}]},{cN:"comment",eB:true,b:"__halt_compiler.+?;",eW:true},{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[a.BE]},{cN:"preprocessor",b:"<\\?php",r:10},{cN:"preprocessor",b:"\\?>"},e,{cN:"function",bWK:true,e:"{",k:"function",i:"\\$|\\[|%",c:[d,{cN:"params",b:"\\(",e:"\\)",c:["self",e,a.CBLCLM].concat(b).concat(c)}]},{cN:"class",bWK:true,e:"{",k:"class",i:"[:\\(\\$]",c:[{bWK:true,eW:true,k:"extends",c:[d]},d]},{b:"=>"}].concat(b).concat(c)}}(hljs);hljs.LANGUAGES.python=function(a){var f={cN:"prompt",b:"^(>>>|\\.\\.\\.) "};var c=[{cN:"string",b:"(u|b)?r?'''",e:"'''",c:[f],r:10},{cN:"string",b:'(u|b)?r?"""',e:'"""',c:[f],r:10},{cN:"string",b:"(u|r|ur)'",e:"'",c:[a.BE],r:10},{cN:"string",b:'(u|r|ur)"',e:'"',c:[a.BE],r:10},{cN:"string",b:"(b|br)'",e:"'",c:[a.BE]},{cN:"string",b:'(b|br)"',e:'"',c:[a.BE]}].concat([a.ASM,a.QSM]);var e={cN:"title",b:a.UIR};var d={cN:"params",b:"\\(",e:"\\)",c:["self",a.CNM,f].concat(c)};var b={bWK:true,e:":",i:"[${=;\\n]",c:[e,d],r:10};return{k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda nonlocal|10",built_in:"None True False Ellipsis NotImplemented"},i:"(</|->|\\?)",c:c.concat([f,a.HCM,a.inherit(b,{cN:"function",k:"def"}),a.inherit(b,{cN:"class",k:"class"}),a.CNM,{cN:"decorator",b:"@",e:"$"},{b:"\\b(print|exec)\\("}])}}(hljs);hljs.LANGUAGES.sql=function(a){return{cI:true,c:[{cN:"operator",b:"(begin|start|commit|rollback|savepoint|lock|alter|create|drop|rename|call|delete|do|handler|insert|load|replace|select|truncate|update|set|show|pragma|grant)\\b(?!:)",e:";",eW:true,k:{keyword:"all partial global month current_timestamp using go revoke smallint indicator end-exec disconnect zone with character assertion to add current_user usage input local alter match collate real then rollback get read timestamp session_user not integer bit unique day minute desc insert execute like ilike|2 level decimal drop continue isolation found where constraints domain right national some module transaction relative second connect escape close system_user for deferred section cast current sqlstate allocate intersect deallocate numeric public preserve full goto initially asc no key output collation group by union session both last language constraint column of space foreign deferrable prior connection unknown action commit view or first into float year primary cascaded except restrict set references names table outer open select size are rows from prepare distinct leading create only next inner authorization schema corresponding option declare precision immediate else timezone_minute external varying translation true case exception join hour default double scroll value cursor descriptor values dec fetch procedure delete and false int is describe char as at in varchar null trailing any absolute current_time end grant privileges when cross check write current_date pad begin temporary exec time update catalog user sql date on identity timezone_hour natural whenever interval work order cascade diagnostics nchar having left call do handler load replace truncate start lock show pragma exists number",aggregate:"count sum min max avg"},c:[{cN:"string",b:"'",e:"'",c:[a.BE,{b:"''"}],r:0},{cN:"string",b:'"',e:'"',c:[a.BE,{b:'""'}],r:0},{cN:"string",b:"`",e:"`",c:[a.BE]},a.CNM]},a.CBLCLM,{cN:"comment",b:"--",e:"$"}]}}(hljs);hljs.LANGUAGES.ini=function(a){return{cI:true,i:"[^\\s]",c:[{cN:"comment",b:";",e:"$"},{cN:"title",b:"^\\[",e:"\\]"},{cN:"setting",b:"^[a-z0-9\\[\\]_-]+[ \\t]*=[ \\t]*",e:"$",c:[{cN:"value",eW:true,k:"on off true false yes no",c:[a.QSM,a.NM]}]}]}}(hljs);hljs.LANGUAGES.perl=function(e){var a="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when";var d={cN:"subst",b:"[$@]\\{",e:"\\}",k:a,r:10};var b={cN:"variable",b:"\\$\\d"};var i={cN:"variable",b:"[\\$\\%\\@\\*](\\^\\w\\b|#\\w+(\\:\\:\\w+)*|[^\\s\\w{]|{\\w+}|\\w+(\\:\\:\\w*)*)"};var f=[e.BE,d,b,i];var h={b:"->",c:[{b:e.IR},{b:"{",e:"}"}]};var g={cN:"comment",b:"^(__END__|__DATA__)",e:"\\n$",r:5};var c=[b,i,e.HCM,g,{cN:"comment",b:"^\\=\\w",e:"\\=cut",eW:true},h,{cN:"string",b:"q[qwxr]?\\s*\\(",e:"\\)",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\[",e:"\\]",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\{",e:"\\}",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\|",e:"\\|",c:f,r:5},{cN:"string",b:"q[qwxr]?\\s*\\<",e:"\\>",c:f,r:5},{cN:"string",b:"qw\\s+q",e:"q",c:f,r:5},{cN:"string",b:"'",e:"'",c:[e.BE],r:0},{cN:"string",b:'"',e:'"',c:f,r:0},{cN:"string",b:"`",e:"`",c:[e.BE]},{cN:"string",b:"{\\w+}",r:0},{cN:"string",b:"-?\\w+\\s*\\=\\>",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"("+e.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[e.HCM,g,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[e.BE],r:0}]},{cN:"sub",bWK:true,e:"(\\s*\\(.*?\\))?[;{]",k:"sub",r:5},{cN:"operator",b:"-\\w\\b",r:0}];d.c=c;h.c[1].c=c;return{k:a,c:c}}(hljs);hljs.LANGUAGES.json=function(a){var e={literal:"true false null"};var d=[a.QSM,a.CNM];var c={cN:"value",e:",",eW:true,eE:true,c:d,k:e};var b={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:true,eE:true,c:[a.BE],i:"\\n",starts:c}],i:"\\S"};var f={b:"\\[",e:"\\]",c:[a.inherit(c,{cN:null})],i:"\\S"};d.splice(d.length,0,b,f);return{c:d,k:e,i:"\\S"}}(hljs);hljs.LANGUAGES.cpp=function(a){var b={keyword:"false int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long throw volatile static protected bool template mutable if public friend do return goto auto void enum else break new extern using true class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue wchar_t inline delete alignof char16_t char32_t constexpr decltype noexcept nullptr static_assert thread_local restrict _Bool complex",built_in:"std string cin cout cerr clog stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr"};return{k:b,i:"</",c:[a.CLCM,a.CBLCLM,a.QSM,{cN:"string",b:"'\\\\?.",e:"'",i:"."},{cN:"number",b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},a.CNM,{cN:"preprocessor",b:"#",e:"$"},{cN:"stl_container",b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:b,r:10,c:["self"]}]}}(hljs);
</script><script>hljs.initHighlightingOnLoad();</script><title>react-native.md</title></head><body><a href="https://github.com/mjp2220/react-native-talk.git"><img class="github" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a><p><a id="top"></a></p>
<h1 id="building-ios-apps-with-javascript-and-react-native">Building iOS Apps with JavaScript and React Native</h1>
<p><em>Quickly build reusable, modular native iOS applications</em></p>
<p>Written and developed by <a href="https://twitter.com/matthew_pic">Matt Piccolella</a> and <a href="https://adicu.com">ADI</a>.</p>
<p>Credit to <a href="http://www.reactnative.com/">Use React Native</a>, <a href="http://www.raywenderlich.com/99473/introducing-react-native-building-apps-javascript">Ray Wenderlich</a>, <a href="https://facebook.github.io/react-native/">Facebook Developers</a>.</p>
<p><strong>Download the sample code <a href="https://dl.dropboxusercontent.com/s/bq23bl6xsgkni68/GithubFinder.zip">here</a>.</strong></p>
<h2 id="getting-started-faqs">Getting Started: FAQs</h2>
<h3 id="what-is-react-native">What is React Native?</h3>
<p>React Native is Facebook's solution to building native iOS and Android applications using JavaScript. It represents the first real attempt to bring web technologies to native mobile development. In the past, solutions like <a href="http://phonegap.com/">PhoneGap</a> have used web-based solutions, which can be slow and unresponsive. With React Native's open source framework for building applications, you can build beautiful mobile applications.</p>
<h3 id="why-should-i-use-it">Why should I use it?</h3>
<p>React Native is built on Facebook's belief that you should "build once, run everywhere." This means that, once you write your application using React Native, you will have both an iOS application and an Android application, which represents incredible time saving. </p>
<p>In addition, React Native doesn't require to rebuild your application each time you make a change, meaning you can "refresh" the page just as you do in web development and see your changes.</p>
<p>Finally, JavaScript is a much more familiar and universal language than Objective-C. Now, you can harness the #skills you have from web programming and put them to use in creating awesome mobile applications, which are much more easily debuggable and stylable.</p>
<h3 id="what-will-this-tutorial-teach-me">What will this tutorial teach me?</h3>
<p>This tutorial will teach you the basics of React Native. We will go through the basic concepts, ranging from React components, to Flexbox and styling, to running your application in XCode. It will NOT teach you all of the methods or possibilities of React Native. If you are interested in learning more in-depth material than this tutorial can offer, <a href="https://github.com/facebook/react-native/tree/master/Examples">examples</a> are available, as well as all the <a href="http://facebook.github.io/react-native/docs/getting-started.html">documentation</a>.</p>
<h2 id="using-this-document">Using this Document</h2>
<p>This document contains a series of several sections, each of which explains a certain sector of our sample iOS application. In each section, we will add some code to our application. All of the code is available both in this document and in the GitHub repo available <a href="https://github.com/mjp2220/react-native-talk">here</a>.</p>
<h2 id="table-of-contents">Table of Contents</h2>
<ul>
<li><a href="#setup">Preface: Setting up your Computer</a></li>
<li><a href="#github-finder">Project Description: GithubFinder</a></li>
<li><a href="#react">1.0 "Hello World" in React Native</a><ul>
<li><a href="#creating-proj">1.1 Creating a Project</a></li>
<li><a href="#using-xcode">1.2 Using XCode</a></li>
<li><a href="#simulator">1.3 Using the Simulator</a></li>
<li><a href="#project-structure">1.4 Project Structure</a></li>
</ul>
</li>
<li><a href="#basics">2.0 The Basics of React</a><ul>
<li><a href="#components">2.1 Components</a></li>
<li><a href="#render">2.2 <code>render</code></a></li>
<li><a href="#styling">2.3 Styling</a></li>
<li><a href="#app-registry">2.4 <code>AppRegistry</code></a></li>
<li><a href="#changing-comp">2.5 Changing our Component</a></li>
</ul>
</li>
<li><a href="#build-application">3.0 Search Bar and Data Retrieval</a><ul>
<li><a href="#search-bar">3.1 Adding our Search Bar</a></li>
<li><a href="#delegate">3.2 Delegate Methods</a></li>
<li><a href="#retrieving-data">3.3 Retrieving our Data</a></li>
</ul>
</li>
<li><a href="#results">4.0 Showing our Results</a><ul>
<li><a href="#component-state">4.1 Component State</a></li>
<li><a href="#list-view">4.2 Creating our List View</a></li>
<li><a href="#cells">4.3 Creating Each Cell</a></li>
<li><a href="#styling-cell">4.4 Styling Each Cell</a></li>
</ul>
</li>
<li><a href="#conclusion">Conclusion</a></li>
<li><a href="#additionalresources">Additional Resources</a></li>
</ul>
<hr />
<p><a id="setup"></a></p>
<h2 id="preface-setting-up-your-computer">Preface: Setting up your Computer</h2>
<p>To use React Native, there are a few requirements that you will need:</p>
<pre><code>1. OS X - as we will be using XCode, your computer must be running Mac OS X.
2. XCode - this is the application that you normally program iOS applications in. For React Native, we will merely run the application using XCode.
3. Homebrew - the recommended package installer for Mac. We will use this to install a few pieces of software we will need.
</code></pre>
<p>To begin the process, please install XCode <a href="https://developer.apple.com/xcode/downloads/">here</a>. To install Homebrew, please run the following command in your Terminal:</p>
<pre><code class="bash">$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
</code></pre>
<p>Once you have XCode and Homebrew installed, please run the following commands from your terminal:</p>
<pre><code class="bash">$ brew install node
$ brew install --HEAD watchman
$ npm install -g react-native-cli
</code></pre>
<p>You may be wondering why we are installing Node, a web technology, when we are working on iOS applications. Node is used by React Native to run our application, which enables the refreshing we will see in a moment.</p>
<p>Once you have installed these, your computer is all setup to program in React Native!</p>
<p><a id="github-finder"></a></p>
<h2 id="project-description-githubfinder">Project Description: GithubFinder</h2>
<p>In this tutorial, we will program a sample application that will allow us to search for projects on GitHub. This will allow to search for applications on GitHub so we can decide whether an application we want to find exists, or whether an application we want to make has been made yet.</p>
<p>Each step of our application will move us toward our final product, which will be our GithubFinder application.</p>
<p><a id="react"></a></p>
<h2 id="10-hello-world-in-react-native">1.0 "Hello World" in React Native</h2>
<p>In this section, we will create our first basic "Hello World" app in React Native. This will show us how to start a project, how to use XCode, how to use the simulator, and what files are involved in our project.</p>
<p><a id="creating-proj"></a></p>
<h3 id="11-creating-a-project">1.1 Creating a Project</h3>
<p>To create our project, we will use the React Native command-line-interface we installed before. To create our application, open your Terminal, navigate to a folder in which you want to keep your project, and type the following command:</p>
<pre><code class="bash">$ react-native init GithubFinder
</code></pre>
<p>If it worked, you should see something like the following output in your Terminal:</p>
<pre><code>Next steps:
Open /Users/Matt/Desktop/GithubFinder/GithubFinder.xcodeproj in Xcode
Hit Run button
</code></pre>
<p>That means we have successfully created our first iOS application using React Native! If you look at the files in our new project folder, you should see something like this:</p>
<pre><code>GithubFinder.xcodeproj iOS index.ios.js
node_modules package.json
</code></pre>
<p>In a later section, we will explain what each one of these files does, and which of them will be important to us.</p>
<p><a id="using-xcode"></a></p>
<h3 id="12-using-xcode">1.2 Using XCode</h3>
<p>Now, let's open our application. So, run XCode, and select:</p>
<pre><code>File > Open
</code></pre>
<p>and from within the directory that was just created, select GithubFinder.xcodeproj. Once you have done this, press the Play button in the top left corner of the application, or simply type <code>Cmd-R</code>, to run your application. Once this happens, a new Terminal window should open with output similar to this:</p>
<pre><code> ===============================================================
| Running packager on port 8081.
| Keep this packager running while developing on any JS
| projects. Feel free to close this tab and run your own
| packager instance if you prefer.
|
| https://github.com/facebook/react-native
|
===============================================================
Looking for JS files in
/Users/Matt/Desktop/GithubFinder
</code></pre>
<p>Don't exit out of this window, as it will package up your JavaScript code into your iOS application. You can minimize both XCode and the Terminal window that was just created; you don't need them anymore!</p>
<p>However, what you will need is the Simulator, which we will take about now.</p>
<p><a id="simulator"></a></p>
<h3 id="13-using-the-simulator">1.3 Using the Simulator</h3>
<p>We will use the Simulator to simulate a real iOS device. We do this because an iOS developer's license is required to run applications on a real device. The simulator looks like this:</p>
<p><img alt="Simulator" src="https://dl.dropboxusercontent.com/s/6utgiyw4hoh5d6e/simulator.png" height="600"/></p>
<p>For us, the simulator is quite simple. To refresh, we simply type <code>Cmd-R</code> to reload our application. Once we start to make changes to our application, you will see how nice this becomes.</p>
<p><a id="project-structure"></a></p>
<h3 id="14-project-structure">1.4 Project Structure</h3>
<p>Now that we have our simulator running, let's go back to the structure of the project we created. We saw before that the files contained inside of our project include:</p>
<pre><code>GithubFinder.xcodeproj iOS index.ios.js
node_modules package.json
</code></pre>
<p>Let's look at each file:</p>
<ul>
<li><code>GithubFinder.xcodeproj</code> - contains details necessary to open our application in XCode. This is what you open when you open XCode.</li>
<li><code>iOS</code> - the file that contains all of the iOS code that is generated by React Native. Important: <strong>IGNORE THIS</strong>, we don't need to worry about it.</li>
<li><code>node_modules</code> - contains the modules necessary for Node. This is also unimportant to us</li>
<li><code>package.json</code> - provides some details about our application</li>
</ul>
<p>These four files are not relevant to us in our creating our application. In fact, there is only one file we need to care about, which is <code>index.ios.js</code>. This makes it super easy for us from a development perspective; in a single file, we can define styles, transitions, and behaviors of our application.</p>
<p>The code of our file looks as follows:</p>
<pre><code class="javascript">/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
} = React;
var GithubFinder = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js
</Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+Control+Z for dev menu
</Text>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
AppRegistry.registerComponent('GithubFinder', () => GithubFinder);
</code></pre>
<p>The code, while it may look familiar in some aspects, has lots of concepts, which will represent most of our work here. The next section will attempt to explain each of the concepts present in this file.</p>
<p><a id="basics"></a></p>
<h2 id="20-the-basics-of-react">2.0 The Basics of React</h2>
<p>In this section, we will disect our <code>index.ios.js</code> file to understand each of the parts that makes up a React application.</p>
<p><a id="components"></a></p>
<h3 id="21-components">2.1 Components</h3>
<p>To start, we can look at the section of the code that looks as follows:</p>
<pre><code class="javascript">var {
AppRegistry,
StyleSheet,
Text,
View,
} = React;
</code></pre>
<p>This is a list of the <strong>components</strong> that we will use in our application. In React, a component is a UI element that we can create; for example, we can have some Text or a View. Components are meant to be <strong>modular</strong>; they represent some small aspect that can be reused. In addition, a major aspect of components is that they are <strong>combinable</strong>; a <code>Text</code> component could reside within a <code>View</code> component, for example.</p>
<p>In this list, we put all of the components that we plan to use. Each of the components listed here is a built-in component that React Native provides us. Other components include <code>Image</code>, <code>TextInput</code>, or <code>ListView</code>. We will see these later.</p>
<p><a id="render"></a></p>
<h3 id="22-render">2.2 <code>render</code></h3>
<p>In this segment of code, we create our first custom component:</p>
<pre><code class="javascript">var GithubFinder = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js
</Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+Control+Z for dev menu
</Text>
</View>
);
}
});
</code></pre>
<p>We use the <code>React.createClass</code> method, which takes a JSON object containing some functions, to create our custom component. Here, we create a component called <code>GithubFinder</code>. This can be viewed the same way as the <code>Text</code> or <code>View</code> components we saw before, and the same concepts apply; we will see that our <code>GithubFinder</code> consists of these very same views.</p>
<p>Inside of this method, we place a single method: <code>render</code>. This method takes no arguments, and simply returns the View that we wish to render for the component. In this case, the View we wish to render looks like this:</p>
<pre><code class="javascript"><View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js
</Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+Control+Z for dev menu
</Text>
</View>
</code></pre>
<p>For those of you familiar with HTML, this looks quite similar: we have nested tags, each of which has some attributes. This reflects the modularity we hope to achieve with React Native. We can write once, use the attributes of the component, and render many different times. Additionally, you may see the character <code>{'\n'}</code>; this is an escape character, and is used to go to the next line in the view.</p>
<p><a id="styling"></a></p>
<h3 id="23-styling">2.3 Styling</h3>
<p>You'll see that on some of our components, there is a <code>style</code> attribute. We define these at the bottom of our file:</p>
<pre><code class="javascript">var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
</code></pre>
<p>Calling the <code>StyleSheet.create</code> function allows us to create lots of different styling rules; think of these as CSS rules, which can define different attributes on the items in question. </p>
<p>Most of the attributes are pretty self-explanatory: <code>color</code>, <code>textAlign</code>, <code>margin</code>, etc. However, <code>flex</code> is one that may be uncommon to some. This is an attribute from <a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/">Flexbox</a>, which is a method for laying out content within a view; for example, moving one item to the left of another item, or something similar.</p>
<p>From this file-wide <code>styles</code> object, we can access all of the different rules we want to use throughout our application. For example, we see we apply <code>styles.container</code> to our <code>View</code> object that will contain all of our <code>Text</code> components.</p>
<p>For those of you that have done Objective-C development, this CSS-like styling is much easier than styling in Interface Builder or something comparable. This will save us a lot of time. In addition, we don't need to reload the entire application to view our styling changes. Try changing <code>textAlign</code> to <code>left</code> instead of <code>center</code>, then go to the Simulator and press <code>Cmd-R</code>; you'll see the text shift without having to reload the entire application. Magic!</p>
<p>Note that React CSS is a subset of the <a href="http://en.wikipedia.org/wiki/Cascading_Style_Sheets">CSS</a> that you may be used to seeing. However, most of the functionality is there in the form of slightly modified names; for example <code>text-align</code> becomes <code>textAlign</code>.</p>
<p><a id="app-registry"></a></p>
<h3 id="24-appregistry">2.4 <code>AppRegistry</code></h3>
<p>Finally, there is a single line at the end of our file:</p>
<pre><code class="javascript">AppRegistry.registerComponent('GithubFinder', () => GithubFinder);
</code></pre>
<p>Our <code>AppRegistry.registerComponent</code> method is the way we register our root component. This means that, when the iOS application launches, it will launch our GithubFinder component as the first component that we see when our application starts. Thus, when our application launches, it'll know what to do.This call will generally be the last line of all of our React Native applications, and it is basically just a way to start our application.</p>
<p><a id="changing-comp"></a></p>
<h3 id="25-changing-our-component">2.5 Changing our Component</h3>
<p>Now that we understand our component, let's change it!</p>
<p>Change <code>render</code> to look as follows:</p>
<pre><code class="javascript">render: function() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
This is my first custom view!
</Text>
<Image
source={{uri : 'http://www.polyvore.com/cgi/img-thing?.out=jpg&size=l&tid=27610859'}}
style={styles.thumbnail}
/>
</View>
);
}
</code></pre>
<p>You may notice we're using <code>{}</code> whenever we're using a variable; these are needed to add a variable name into the HTML. This is needed because when we want to add styles, for example, we want to refer to the <code>styles</code> variable, not just the word 'styles.' Additionally, for the <code>source</code> attribute of our <code><Image></code> tag, we include a second pair of <code>{}</code> to indicate a JavaScript object, which is taken by the attribute.</p>
<p>Next, change our <code>styles</code> object so that it looks like this:</p>
<pre><code class="javascript">var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
customimg: {
width: 200,
height: 200,
},
});
</code></pre>
<p>This provides a width and height for the <code>Image</code> object we are adding.</p>
<p>One more thing that we have to do is require the <code>Image</code> component, which we are now using. We do that by changing our <code>React</code> object at the top as follows:</p>
<pre><code class="javascript">var {
AppRegistry,
Image,
StyleSheet,
Text,
View,
} = React;
</code></pre>
<p>Now, our application code will look as follows:</p>
<pre><code class="javascript">'use strict';
var React = require('react-native');
var {
AppRegistry,
Image,
StyleSheet,
Text,
View,
} = React;
var GithubFinder = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text>
This is my first custom view!
</Text>
<Image
source={{uri : 'http://www.polyvore.com/cgi/img-thing?.out=jpg&size=l&tid=27610859'}}
style={styles.customimg}
/>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
customimg: {
width: 200,
height: 200,
},
});
AppRegistry.registerComponent('GithubFinder', () => GithubFinder);
</code></pre>
<p>and our application will look as follows:</p>
<p><img alt="Custom View" src="https://dl.dropboxusercontent.com/s/sp5s2goau3ucaa9/first-view.png" height="600"/></p>
<p>Woohoo! You have now created your first custom view.</p>
<p><a id="build-application"></a></p>
<h2 id="30-search-bar-and-data-retrieval">3.0 Search Bar and Data Retrieval</h2>
<p>Now we are going to work on getting our data. To do this, we will use the GitHub API, which is pretty simple and easy to get the hang of. Let's begin.</p>
<p><a id="search-bar"></a></p>
<h3 id="31-adding-our-search-bar">3.1 Adding our Search Bar</h3>
<p>First, we need to add our search bar. We'll do this by adding a simple <code>TextInput</code> and adding some styling. Change your <code>render</code> method to the following:</p>
<pre><code class="javascript">render: function() {
return (
<View style={styles.container}>
<TextInput
autoCapitalize="none"
autoCorrect={false}
placeholder="Search for a project..."
style={styles.searchBarInput}
/>
</View>
);
}
</code></pre>
<p>We basically create a <code>TextInput</code> object with several different attributes: we don't want our words to autocapitalize or autocorrect, we add a placeholder text, and some styles, which are as follows:</p>
<pre><code class="javascript">var styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
},
searchBarInput: {
marginTop: 30,
padding: 5,
fontSize: 15,
flex: 1,
height: 30,
backgroundColor: '#EAEAEA',
},
});
</code></pre>
<p>We change the background color of our <code>TextInput</code> to make it more visible, set its height and top margin, give it some padding, and we're done. The completed view looks like this:</p>
<p><img alt="Search Bar" src="https://dl.dropboxusercontent.com/s/0daztpubink5xqz/searchbar.png" height="600"/></p>
<p><a id="delegate"></a></p>
<h3 id="32-delegate-methods">3.2 Delegate Methods</h3>
<p>Now, we want to be able to search for our API whenever a user types into the search bar. To do this, we need to use a <strong>delegate method</strong>. Essentially what this means is that we want a certain function to be called after some action, in this case whenever the user stops typing in the search bar. To do that, we simply set the property <code>onEndEditing</code> on the text input, as follows:</p>
<pre><code class="javascript"><TextInput
autoCapitalize="none"
autoCorrect={false}
placeholder="Search for a project..."
style={styles.searchBarInput}
onEndEditing={this.onSearchChange}
/>
</code></pre>
<p>We have not yet implemented this function to actually query the GitHub API to get our data on the search change, but we will do that next.</p>
<p><a id="retrieving-data"></a></p>
<h3 id="33-retrieving-our-data">3.3 Retrieving our Data</h3>
<p>So, now we must implement our function <code>onSearchChange</code> to query the GitHub API for our results. Let's implement that as follows:</p>
<pre><code class="javascript">var BASE_URL = 'https://api.github.com/search/repositories?q=';
...
var GithubFinder = React.createClass({
...
onSearchChange: function(event: Object) {
var searchTerm = event.nativeEvent.text.toLowerCase();
var queryURL = BASE_URL + encodeURIComponent(searchTerm);
fetch(queryURL)
.then((response) => response.json())
.then((responseData) => {
if (responseData.items) {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData.items),
});
}
})
.done();
},
});
</code></pre>
<p>Inside of our function, we create our URL by appending the text that was typed into the search bar. Then, we use our <code>fetch</code> method to find the results of the API call, then once we have the data available, we set the state of our component to include our data source. However, we also check that our items exist; we could have a blank response or an error response which would make us not want to change the data source. We refer to <code>responseData.items</code> because that is the response in which our data comes back; try clicking on [https://api.github.com/search/repositories?q=tetris] and you'll see the format of the object we'll be working with.</p>
<p>Also, the syntax with <code>=></code> may be confused, as it is something that React uses quite heavily. Essentially it is a way to define a function inline, allowing us to do something with the parameter that is in parentheses immediately before it on the line. We can either simply return an object, like we do with <code>response.json()</code>, or we can create a function bounded by curly brackets, which we do on the line with <code>responseData</code>.</p>
<p>We will talk more about the data source line in our next section, but essentially what it does it store the data so we will be able to access it later.</p>
<p>Now, we are done with the data retrieval part of our app! Let's move on to presenting it.</p>
<p>Our code thus far looks as follows:</p>
<pre><code class="javascript">'use strict';
var React = require('react-native');
var BASE_URL = "https://api.github.com/search/repositories?q=";
var {
AppRegistry,
Image,
ListView,
StyleSheet,
Text,
TextInput,
View,
} = React;
var GithubFinder = React.createClass({
render: function() {
return (
<View style={styles.container}>
<TextInput
autoCapitalize="none"
autoCorrect={false}
placeholder="Search for a project..."
style={styles.searchBarInput}
onEndEditing={this.onSearchChange}
/>
</View>
);
},
onSearchChange: function(event: Object) {
var searchTerm = event.nativeEvent.text.toLowerCase();
var queryURL = BASE_URL + encodeURIComponent(searchTerm);
fetch(queryURL)
.then((response) => response.json())
.then((responseData) => {
if (responseData.items) {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData.items),
});
}
})
.done();
},
});
var styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
},
searchBarInput: {
marginTop: 30,
padding: 5,
fontSize: 15,
flex: 1,
height: 30,
backgroundColor: '#EAEAEA',
},
});
AppRegistry.registerComponent('GithubFinder', () => GithubFinder);
</code></pre>
<p><a id="results"></a></p>
<h2 id="40-showing-our-results">4.0 Showing our Results</h2>
<p>Now that we have our data, let's work on presenting it in the form of a list view. In this list view, each row will correspond to a different repository that was returned by our search to GitHub. Let's do it!</p>
<p><a id="component-state"></a></p>
<h3 id="41-component-state">4.1 Component State</h3>
<p>In the previous section, we called the method <code>this.setState</code>. An important aspect of React that we haven't yet introduced is that each Component has its own <strong>state</strong>, which represents some data we can store about a component. In this case, we want to store a data source, which is the data that our list view will present. When our component is first rendered, we want to set an initial state, which we do using the method <code>getInitialState</code>. Let's implement it as follows:</p>
<pre><code class="javascript">var GithubFinder = React.createClass({
...
getInitialState: function() {
return {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}),
};
},
...
});
</code></pre>
<p><strong>NOTE</strong>: since we are now using <code>ListView</code>, we need to add it to our list of components at the top of our file:</p>
<pre><code>var {
AppRegistry,
Image,
ListView,
StyleSheet,
Text,
TextInput,
View,
} = React;
</code></pre>
<p>In this, we create a blank data source with a single attribute, a function which defines whether a row has changed. Don't worry too much about this; all it does is tell the data source that a row has changed if the two rows aren't equal.</p>
<p>Now that we have set our initial state, our data retrieval method will be able to successfully set the rows of our data source using the GitHub search results. We do this so later when we have new data, we can go ahead and alter our original data source to show our new results.</p>
<p><a id="list-view"></a></p>
<h3 id="42-creating-our-list-view">4.2 Creating our List View</h3>
<p>Now, we need to create our list view to show all the results we have loaded. Let's do that. We can simply add a component to our <code>render</code> method as follows:</p>
<pre><code class="javascript"> render: function() {
var content;
if (this.state.dataSource.getRowCount() === 0) {
content =
<Text>
Please enter a search term to see results.
</Text>;
else {
content =
<ListView
ref="listview"
dataSource={this.state.dataSource}
renderRow={this.renderRow}
automaticallyAdjustContentInsets={false}
keyboardDismissMode="onDrag"
keyboardShouldPersistTaps={true}
showsVerticalScrollIndicator={true}
/>;
}
return (
<View style={styles.container}>
<TextInput
autoCapitalize="none"
autoCorrect={false}
placeholder="Search for a project..."
style={styles.searchBarInput}
onEndEditing={this.onSearchChange}
/>
{content}
</View>
);
},
</code></pre>
<p>Let's look at this piece by piece. First, we add our search bar, just like we did before. Then, we do create a variable, called <code>content</code>, which will define what is put next in our view. If our data source doesn't have any rows, meaning we don't have any data results to show, we prompt the user to enter a search term. If, however, we do have search results, then we add a list view. </p>
<p>Our List View object has several attributes that we must set. One is our data source, the source from which the list will render itself. Next, we provide a method, called <code>renderRow</code>, which will render each row in the list; we'll implement that next. Then, we implement several styling keywords that help to define the actions of our <code>ListView</code>; there are many different available properties and those can be found in the documentation.</p>
<p><a id="cells"></a></p>
<h3 id="43-creating-each-cell">4.3 Creating Each Cell</h3>
<p>Now, we want to show row to render each of our rows. We do that by implementing a the method that we placed as our delegate method for rendering rows, <code>this.renderRow</code>. We can implement that here:</p>
<pre><code class="javascript">renderRow: function(repo: Object) {
return (
<View>
<View style={styles.row}>
<Text>
{repo.name}
</Text>
</View>
<View style={styles.cellBorder} />
</View>
);
},
</code></pre>
<p>Here, we create a basic row that shows just the name of the searched-for repository.</p>
<p>We add two rules to our styles, <code>row</code> and <code>cellBorder</code> to provide the basic rules for our cells:</p>
<pre><code class="javascript">row: {
alignItems: 'center',
backgroundColor: 'white',
flexDirection: 'row',
padding: 5,
},
cellBorder: {
backgroundColor: 'rgba(0, 0, 0, 0.1)',
height: 1,
marginLeft: 4,
},
</code></pre>
<p>Now, if we search for an object, we will see our basic results:</p>
<p><img alt="Basic List View" src="https://dl.dropboxusercontent.com/s/1jg46adqi74g0pb/Screen%20Shot%202015-04-13%20at%201.03.15%20AM.png" height="600"/></p>
<p>We're almost done with our app!</p>
<p><a id="styling-cell"></a></p>
<h3 id="44-styling-each-cell">4.4 Styling Each Cell</h3>
<p>Now, let's add some more detail to our row, and style it so it looks nicer.</p>
<p>First, we're going to add the user's profile image to the row. Next, we're going to add both the user's name and the name of the repository. We will use some style to set one as the title and one as the subtitle. Then, we will create some styling for the container so padding looks correct.</p>
<p>Here's our edited <code>renderRow</code> function:</p>
<pre><code class="javascript">renderRow: function(repo: Object) {
return (
<View>
<View style={styles.row}>
<Image
source={{uri: repo.owner.avatar_url}}
style={styles.profpic}
/>
<View style={styles.textcontainer}>
<Text style={styles.title}>{repo.name}</Text>
<Text style={styles.subtitle}>{repo.owner.login}</Text>
</View>
</View>
<View style={styles.cellBorder} />
</View>
);
},
</code></pre>
<p>Finally, here are all the styles that are newly created:</p>
<pre><code class="javascript">profpic: {
width: 50,
height: 50,
},
title: {
fontSize: 20,
marginBottom: 8,
fontWeight: 'bold'
},
subtitle: {