mirror of
https://github.com/LukeHagar/unicorn-utterances.git
synced 2025-12-07 21:07:47 +00:00
chore: add React Unidirectionality article
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
<svg width="729" height="380" viewBox="0 0 729 380" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d)">
|
||||
<mask id="path-1-inside-1" fill="white">
|
||||
<path d="M95 230H260V278H95V230Z"/>
|
||||
</mask>
|
||||
<path d="M95 230H260V278H95V230Z" fill="#EFC4FF"/>
|
||||
<path d="M95 230V228H93V230H95ZM260 230H262V228H260V230ZM260 278V280H262V278H260ZM95 278H93V280H95V278ZM95 232H260V228H95V232ZM258 230V278H262V230H258ZM260 276H95V280H260V276ZM97 278V230H93V278H97Z" fill="black" mask="url(#path-1-inside-1)"/>
|
||||
<path d="M153.902 254.775L157.799 256.149V258.063L151.913 255.568V253.955L157.799 251.46V253.374L153.902 254.775ZM167.369 255.685C167.292 256.756 166.895 257.599 166.18 258.214C165.469 258.829 164.53 259.137 163.363 259.137C162.087 259.137 161.082 258.708 160.349 257.852C159.619 256.99 159.255 255.81 159.255 254.311V253.702C159.255 252.745 159.424 251.902 159.761 251.173C160.098 250.444 160.579 249.885 161.203 249.498C161.832 249.106 162.561 248.91 163.391 248.91C164.539 248.91 165.464 249.218 166.166 249.833C166.868 250.448 167.273 251.312 167.383 252.424H165.332C165.282 251.781 165.102 251.316 164.792 251.029C164.487 250.738 164.02 250.592 163.391 250.592C162.707 250.592 162.194 250.838 161.853 251.33C161.515 251.818 161.342 252.576 161.333 253.606V254.358C161.333 255.434 161.495 256.22 161.818 256.717C162.146 257.214 162.661 257.462 163.363 257.462C163.997 257.462 164.468 257.318 164.778 257.031C165.093 256.74 165.273 256.291 165.318 255.685H167.369ZM170.514 252.41C171.038 251.781 171.696 251.467 172.489 251.467C174.093 251.467 174.907 252.399 174.93 254.263V259H172.954V254.317C172.954 253.894 172.863 253.581 172.681 253.381C172.498 253.176 172.195 253.073 171.771 253.073C171.193 253.073 170.773 253.297 170.514 253.743V259H168.538V248.5H170.514V252.41ZM178.505 259H176.522V251.604H178.505V259ZM176.406 249.689C176.406 249.393 176.504 249.149 176.7 248.958C176.901 248.767 177.172 248.671 177.514 248.671C177.851 248.671 178.12 248.767 178.32 248.958C178.521 249.149 178.621 249.393 178.621 249.689C178.621 249.99 178.519 250.236 178.313 250.428C178.113 250.619 177.846 250.715 177.514 250.715C177.181 250.715 176.912 250.619 176.707 250.428C176.507 250.236 176.406 249.99 176.406 249.689ZM182.224 259H180.241V248.5H182.224V259ZM183.55 255.247C183.55 254.094 183.807 253.176 184.322 252.492C184.842 251.809 185.55 251.467 186.448 251.467C187.168 251.467 187.763 251.736 188.232 252.273V248.5H190.215V259H188.431L188.335 258.214C187.843 258.829 187.209 259.137 186.435 259.137C185.564 259.137 184.865 258.795 184.336 258.111C183.812 257.423 183.55 256.468 183.55 255.247ZM185.525 255.391C185.525 256.083 185.646 256.614 185.888 256.983C186.129 257.353 186.48 257.537 186.94 257.537C187.551 257.537 187.982 257.28 188.232 256.765V253.846C187.986 253.331 187.56 253.073 186.954 253.073C186.002 253.073 185.525 253.846 185.525 255.391ZM192.368 259.854H190.898L194.562 249.047H196.032L192.368 259.854ZM201.016 254.755L197.044 253.367V251.467L202.998 253.962V255.568L197.044 258.07V256.163L201.016 254.755Z" fill="black"/>
|
||||
</g>
|
||||
<g filter="url(#filter1_d)">
|
||||
<rect width="165" height="48" transform="translate(95 103)" fill="#99DBFF"/>
|
||||
<mask id="path-4-inside-2" fill="white">
|
||||
<path d="M95 103H260V151H95V103Z"/>
|
||||
</mask>
|
||||
<path d="M95 103H260V151H95V103Z" fill="#99DBFF"/>
|
||||
<path d="M95 103V101H93V103H95ZM260 103H262V101H260V103ZM260 151V153H262V151H260ZM95 151H93V153H95V151ZM95 105H260V101H95V105ZM258 103V151H262V103H258ZM260 149H95V153H260V149ZM97 151V103H93V151H97Z" fill="black" mask="url(#path-4-inside-2)"/>
|
||||
<path d="M149.268 127.775L153.164 129.149V131.063L147.278 128.568V126.955L153.164 124.46V126.374L149.268 127.775ZM156.972 128.493V132H154.921V122.047H158.804C159.551 122.047 160.207 122.184 160.772 122.457C161.342 122.73 161.78 123.12 162.085 123.626C162.39 124.127 162.543 124.699 162.543 125.342C162.543 126.317 162.208 127.087 161.538 127.652C160.873 128.213 159.95 128.493 158.77 128.493H156.972ZM156.972 126.832H158.804C159.346 126.832 159.758 126.704 160.041 126.449C160.328 126.194 160.472 125.829 160.472 125.355C160.472 124.868 160.328 124.474 160.041 124.173C159.754 123.872 159.357 123.717 158.852 123.708H156.972V126.832ZM168.032 132C167.941 131.822 167.875 131.601 167.834 131.337C167.355 131.87 166.733 132.137 165.968 132.137C165.243 132.137 164.642 131.927 164.163 131.508C163.689 131.089 163.452 130.56 163.452 129.922C163.452 129.138 163.742 128.536 164.32 128.117C164.904 127.698 165.744 127.486 166.843 127.481H167.752V127.058C167.752 126.716 167.663 126.442 167.485 126.237C167.312 126.032 167.036 125.93 166.658 125.93C166.326 125.93 166.063 126.009 165.872 126.169C165.685 126.328 165.592 126.547 165.592 126.825H163.616C163.616 126.397 163.748 126 164.013 125.636C164.277 125.271 164.651 124.986 165.134 124.781C165.617 124.572 166.159 124.467 166.761 124.467C167.672 124.467 168.395 124.697 168.928 125.157C169.465 125.613 169.734 126.256 169.734 127.085V130.291C169.739 130.993 169.837 131.524 170.028 131.884V132H168.032ZM166.398 130.626C166.69 130.626 166.959 130.562 167.205 130.435C167.451 130.302 167.633 130.127 167.752 129.908V128.637H167.014C166.025 128.637 165.498 128.979 165.435 129.662L165.428 129.778C165.428 130.024 165.514 130.227 165.688 130.387C165.861 130.546 166.098 130.626 166.398 130.626ZM175.408 126.456C175.139 126.42 174.902 126.401 174.697 126.401C173.95 126.401 173.46 126.654 173.228 127.16V132H171.252V124.604H173.118L173.173 125.485C173.569 124.806 174.118 124.467 174.82 124.467C175.039 124.467 175.244 124.496 175.436 124.556L175.408 126.456ZM179.633 132.137C178.548 132.137 177.664 131.804 176.98 131.139C176.301 130.473 175.962 129.587 175.962 128.479V128.288C175.962 127.545 176.105 126.882 176.393 126.299C176.68 125.711 177.085 125.26 177.609 124.945C178.138 124.626 178.74 124.467 179.414 124.467C180.426 124.467 181.221 124.786 181.8 125.424C182.383 126.062 182.675 126.966 182.675 128.138V128.944H177.965C178.029 129.427 178.22 129.815 178.539 130.106C178.863 130.398 179.271 130.544 179.763 130.544C180.524 130.544 181.118 130.268 181.547 129.717L182.518 130.804C182.221 131.223 181.82 131.551 181.314 131.788C180.809 132.021 180.248 132.137 179.633 132.137ZM179.407 126.066C179.015 126.066 178.696 126.199 178.45 126.463C178.209 126.727 178.054 127.105 177.985 127.598H180.733V127.44C180.724 127.003 180.606 126.666 180.378 126.429C180.15 126.187 179.826 126.066 179.407 126.066ZM185.621 124.604L185.683 125.458C186.211 124.797 186.92 124.467 187.809 124.467C188.592 124.467 189.176 124.697 189.559 125.157C189.941 125.618 190.137 126.306 190.146 127.222V132H188.171V127.27C188.171 126.85 188.08 126.547 187.897 126.36C187.715 126.169 187.412 126.073 186.988 126.073C186.432 126.073 186.015 126.31 185.737 126.784V132H183.762V124.604H185.621ZM194.016 122.785V124.604H195.28V126.053H194.016V129.744C194.016 130.018 194.068 130.214 194.173 130.332C194.278 130.451 194.478 130.51 194.774 130.51C194.993 130.51 195.187 130.494 195.355 130.462V131.959C194.968 132.077 194.569 132.137 194.159 132.137C192.774 132.137 192.067 131.437 192.04 130.038V126.053H190.96V124.604H192.04V122.785H194.016ZM197.003 132.854H195.533L199.197 122.047H200.667L197.003 132.854ZM205.65 127.755L201.679 126.367V124.467L207.633 126.962V128.568L201.679 131.07V129.163L205.65 127.755Z" fill="black"/>
|
||||
</g>
|
||||
<path d="M227.081 172.919L234 164.919L240.919 172.919" stroke="black" stroke-width="2" stroke-linecap="square"/>
|
||||
<path d="M240.838 208L233.919 216L227 208" stroke="black" stroke-width="2" stroke-linecap="square"/>
|
||||
<path d="M234 165V216" stroke="black" stroke-width="2"/>
|
||||
<path d="M115.081 172.919L122 164.919L128.919 172.919" stroke="black" stroke-width="2" stroke-linecap="square"/>
|
||||
<path d="M128.838 208L121.919 216L115 208" stroke="black" stroke-width="2" stroke-linecap="square"/>
|
||||
<path d="M122 165V216" stroke="black" stroke-width="2"/>
|
||||
<g filter="url(#filter2_d)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M272.22 300.22L67.7802 95.7802C67.3452 96.2885 66.9138 96.7999 66.4858 97.3142C50.6335 116.366 39.5711 139.544 35.1471 165L35.1001 165.272C33.7194 173.308 33 181.57 33 190C33 270.081 97.9187 335 178 335C213.247 335 245.556 322.424 270.686 301.514C271.2 301.086 271.711 300.655 272.22 300.22ZM269.266 300.094L67.906 98.7344C52.3339 117.498 41.4691 140.304 37.1176 165.342L37.0712 165.611C35.7096 173.535 35 181.684 35 190C35 268.977 99.0233 333 178 333C212.696 333 244.502 320.646 269.266 300.094ZM276.02 294.121L73.8792 91.9797C93.2924 71.3661 118.755 56.5197 147.426 50.2755C157.275 48.1304 167.504 47 178 47C256.977 47 321 111.023 321 190C321 231.04 303.714 268.04 276.02 294.121ZM71.1017 92.0306L275.969 296.898C304.877 270.391 323 232.312 323 190C323 109.919 258.081 45 178 45C167.36 45 156.988 46.146 147 48.3213C117.269 54.7966 90.9432 70.3924 71.1017 92.0306ZM330 190C330 273.947 261.947 342 178 342C94.0527 342 26 273.947 26 190C26 181.476 26.7018 173.115 28.0512 164.971C28.0678 164.87 28.0846 164.77 28.1015 164.669C38.4383 103.055 85.835 54.0158 146.589 41.2498C156.726 39.1198 167.233 38 178 38C261.947 38 330 106.053 330 190ZM328 190C328 272.843 260.843 340 178 340C95.1573 340 28 272.843 28 190C28 181.586 28.6927 173.334 30.0242 165.298C30.0407 165.199 30.0573 165.099 30.074 165C40.2741 104.201 87.0485 55.8045 147 43.2071C157.003 41.1053 167.372 40 178 40C260.843 40 328 107.157 328 190Z" fill="black"/>
|
||||
</g>
|
||||
<g filter="url(#filter3_d)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M178 340C260.843 340 328 272.843 328 190C328 107.157 260.843 40 178 40C167.372 40 157.003 41.1053 147 43.2071C87.0485 55.8045 40.2741 104.201 30.074 165C30.0573 165.099 30.0407 165.199 30.0242 165.298C28.6927 173.334 28 181.586 28 190C28 272.843 95.1573 340 178 340ZM178 335C213.968 335 246.877 321.904 272.22 300.22L67.7802 95.7802C51.2357 115.116 39.6906 138.857 35.1471 165C35.1314 165.091 35.1157 165.181 35.1001 165.272C33.7194 173.308 33 181.57 33 190C33 270.081 97.9187 335 178 335ZM275.969 296.898L71.1017 92.0306C90.9432 70.3924 117.269 54.7966 147 48.3213C156.988 46.146 167.36 45 178 45C258.081 45 323 109.919 323 190C323 232.312 304.877 270.391 275.969 296.898Z" fill="#FFC2C2"/>
|
||||
</g>
|
||||
<g filter="url(#filter4_d)">
|
||||
<rect width="165" height="48" transform="translate(470 230)" fill="#EFC3FF"/>
|
||||
<mask id="path-15-inside-3" fill="white">
|
||||
<path d="M470 230H635V278H470V230Z"/>
|
||||
</mask>
|
||||
<path d="M470 230H635V278H470V230Z" fill="#EFC3FF"/>
|
||||
<path d="M470 230V228H468V230H470ZM635 230H637V228H635V230ZM635 278V280H637V278H635ZM470 278H468V280H470V278ZM470 232H635V228H470V232ZM633 230V278H637V230H633ZM635 276H470V280H635V276ZM472 278V230H468V278H472Z" fill="black" mask="url(#path-15-inside-3)"/>
|
||||
<path d="M528.902 254.775L532.799 256.149V258.063L526.913 255.568V253.955L532.799 251.46V253.374L528.902 254.775ZM542.369 255.685C542.292 256.756 541.895 257.599 541.18 258.214C540.469 258.829 539.53 259.137 538.363 259.137C537.087 259.137 536.082 258.708 535.349 257.852C534.619 256.99 534.255 255.81 534.255 254.311V253.702C534.255 252.745 534.424 251.902 534.761 251.173C535.098 250.444 535.579 249.885 536.203 249.498C536.832 249.106 537.561 248.91 538.391 248.91C539.539 248.91 540.464 249.218 541.166 249.833C541.868 250.448 542.273 251.312 542.383 252.424H540.332C540.282 251.781 540.102 251.316 539.792 251.029C539.487 250.738 539.02 250.592 538.391 250.592C537.707 250.592 537.194 250.838 536.853 251.33C536.515 251.818 536.342 252.576 536.333 253.606V254.358C536.333 255.434 536.495 256.22 536.818 256.717C537.146 257.214 537.661 257.462 538.363 257.462C538.997 257.462 539.468 257.318 539.778 257.031C540.093 256.74 540.273 256.291 540.318 255.685H542.369ZM545.514 252.41C546.038 251.781 546.696 251.467 547.489 251.467C549.093 251.467 549.907 252.399 549.93 254.263V259H547.954V254.317C547.954 253.894 547.863 253.581 547.681 253.381C547.498 253.176 547.195 253.073 546.771 253.073C546.193 253.073 545.773 253.297 545.514 253.743V259H543.538V248.5H545.514V252.41ZM553.505 259H551.522V251.604H553.505V259ZM551.406 249.689C551.406 249.393 551.504 249.149 551.7 248.958C551.901 248.767 552.172 248.671 552.514 248.671C552.851 248.671 553.12 248.767 553.32 248.958C553.521 249.149 553.621 249.393 553.621 249.689C553.621 249.99 553.519 250.236 553.313 250.428C553.113 250.619 552.846 250.715 552.514 250.715C552.181 250.715 551.912 250.619 551.707 250.428C551.507 250.236 551.406 249.99 551.406 249.689ZM557.224 259H555.241V248.5H557.224V259ZM558.55 255.247C558.55 254.094 558.807 253.176 559.322 252.492C559.842 251.809 560.55 251.467 561.448 251.467C562.168 251.467 562.763 251.736 563.232 252.273V248.5H565.215V259H563.431L563.335 258.214C562.843 258.829 562.209 259.137 561.435 259.137C560.564 259.137 559.865 258.795 559.336 258.111C558.812 257.423 558.55 256.468 558.55 255.247ZM560.525 255.391C560.525 256.083 560.646 256.614 560.888 256.983C561.129 257.353 561.48 257.537 561.94 257.537C562.551 257.537 562.982 257.28 563.232 256.765V253.846C562.986 253.331 562.56 253.073 561.954 253.073C561.002 253.073 560.525 253.846 560.525 255.391ZM567.368 259.854H565.898L569.562 249.047H571.032L567.368 259.854ZM576.016 254.755L572.044 253.367V251.467L577.998 253.962V255.568L572.044 258.07V256.163L576.016 254.755Z" fill="black"/>
|
||||
</g>
|
||||
<g filter="url(#filter5_d)">
|
||||
<rect width="165" height="48" transform="translate(470 103)" fill="#99DBFF"/>
|
||||
<mask id="path-18-inside-4" fill="white">
|
||||
<path d="M470 103H635V151H470V103Z"/>
|
||||
</mask>
|
||||
<path d="M470 103H635V151H470V103Z" fill="#99DBFF"/>
|
||||
<path d="M470 103V101H468V103H470ZM635 103H637V101H635V103ZM635 151V153H637V151H635ZM470 151H468V153H470V151ZM470 105H635V101H470V105ZM633 103V151H637V103H633ZM635 149H470V153H635V149ZM472 151V103H468V151H472Z" fill="black" mask="url(#path-18-inside-4)"/>
|
||||
<path d="M524.268 127.775L528.164 129.149V131.063L522.278 128.568V126.955L528.164 124.46V126.374L524.268 127.775ZM531.972 128.493V132H529.921V122.047H533.804C534.551 122.047 535.207 122.184 535.772 122.457C536.342 122.73 536.78 123.12 537.085 123.626C537.39 124.127 537.543 124.699 537.543 125.342C537.543 126.317 537.208 127.087 536.538 127.652C535.873 128.213 534.95 128.493 533.77 128.493H531.972ZM531.972 126.832H533.804C534.346 126.832 534.758 126.704 535.041 126.449C535.328 126.194 535.472 125.829 535.472 125.355C535.472 124.868 535.328 124.474 535.041 124.173C534.754 123.872 534.357 123.717 533.852 123.708H531.972V126.832ZM543.032 132C542.941 131.822 542.875 131.601 542.834 131.337C542.355 131.87 541.733 132.137 540.968 132.137C540.243 132.137 539.642 131.927 539.163 131.508C538.689 131.089 538.452 130.56 538.452 129.922C538.452 129.138 538.742 128.536 539.32 128.117C539.904 127.698 540.744 127.486 541.843 127.481H542.752V127.058C542.752 126.716 542.663 126.442 542.485 126.237C542.312 126.032 542.036 125.93 541.658 125.93C541.326 125.93 541.063 126.009 540.872 126.169C540.685 126.328 540.592 126.547 540.592 126.825H538.616C538.616 126.397 538.748 126 539.013 125.636C539.277 125.271 539.651 124.986 540.134 124.781C540.617 124.572 541.159 124.467 541.761 124.467C542.672 124.467 543.395 124.697 543.928 125.157C544.465 125.613 544.734 126.256 544.734 127.085V130.291C544.739 130.993 544.837 131.524 545.028 131.884V132H543.032ZM541.398 130.626C541.69 130.626 541.959 130.562 542.205 130.435C542.451 130.302 542.633 130.127 542.752 129.908V128.637H542.014C541.025 128.637 540.498 128.979 540.435 129.662L540.428 129.778C540.428 130.024 540.514 130.227 540.688 130.387C540.861 130.546 541.098 130.626 541.398 130.626ZM550.408 126.456C550.139 126.42 549.902 126.401 549.697 126.401C548.95 126.401 548.46 126.654 548.228 127.16V132H546.252V124.604H548.118L548.173 125.485C548.569 124.806 549.118 124.467 549.82 124.467C550.039 124.467 550.244 124.496 550.436 124.556L550.408 126.456ZM554.633 132.137C553.548 132.137 552.664 131.804 551.98 131.139C551.301 130.473 550.962 129.587 550.962 128.479V128.288C550.962 127.545 551.105 126.882 551.393 126.299C551.68 125.711 552.085 125.26 552.609 124.945C553.138 124.626 553.74 124.467 554.414 124.467C555.426 124.467 556.221 124.786 556.8 125.424C557.383 126.062 557.675 126.966 557.675 128.138V128.944H552.965C553.029 129.427 553.22 129.815 553.539 130.106C553.863 130.398 554.271 130.544 554.763 130.544C555.524 130.544 556.118 130.268 556.547 129.717L557.518 130.804C557.221 131.223 556.82 131.551 556.314 131.788C555.809 132.021 555.248 132.137 554.633 132.137ZM554.407 126.066C554.015 126.066 553.696 126.199 553.45 126.463C553.209 126.727 553.054 127.105 552.985 127.598H555.733V127.44C555.724 127.003 555.606 126.666 555.378 126.429C555.15 126.187 554.826 126.066 554.407 126.066ZM560.621 124.604L560.683 125.458C561.211 124.797 561.92 124.467 562.809 124.467C563.592 124.467 564.176 124.697 564.559 125.157C564.941 125.618 565.137 126.306 565.146 127.222V132H563.171V127.27C563.171 126.85 563.08 126.547 562.897 126.36C562.715 126.169 562.412 126.073 561.988 126.073C561.432 126.073 561.015 126.31 560.737 126.784V132H558.762V124.604H560.621ZM569.016 122.785V124.604H570.28V126.053H569.016V129.744C569.016 130.018 569.068 130.214 569.173 130.332C569.278 130.451 569.478 130.51 569.774 130.51C569.993 130.51 570.187 130.494 570.355 130.462V131.959C569.968 132.077 569.569 132.137 569.159 132.137C567.774 132.137 567.067 131.437 567.04 130.038V126.053H565.96V124.604H567.04V122.785H569.016ZM572.003 132.854H570.533L574.197 122.047H575.667L572.003 132.854ZM580.65 127.755L576.679 126.367V124.467L582.633 126.962V128.568L576.679 131.07V129.163L580.65 127.755Z" fill="black"/>
|
||||
</g>
|
||||
<path d="M615.838 208L608.919 216L602 208" stroke="black" stroke-width="2" stroke-linecap="square"/>
|
||||
<path d="M610 165C610 164.448 609.552 164 609 164C608.448 164 608 164.448 608 165H610ZM608 165V216H610V165H608Z" fill="black"/>
|
||||
<path d="M490.081 172.919L497 164.919L503.919 172.919" stroke="black" stroke-width="2" stroke-linecap="square"/>
|
||||
<path d="M496 216C496 216.552 496.448 217 497 217C497.552 217 498 216.552 498 216H496ZM496 165V216H498V165H496Z" fill="black"/>
|
||||
<g filter="url(#filter6_d)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M553 335C633.081 335 698 270.081 698 190C698 109.919 633.081 45 553 45C472.919 45 408 109.919 408 190C408 270.081 472.919 335 553 335ZM553 340C635.843 340 703 272.843 703 190C703 107.157 635.843 40 553 40C470.157 40 403 107.157 403 190C403 272.843 470.157 340 553 340Z" fill="#B3FF99"/>
|
||||
<path d="M697 190C697 269.529 632.529 334 553 334C473.471 334 409 269.529 409 190C409 110.471 473.471 46 553 46C632.529 46 697 110.471 697 190ZM553 341C636.395 341 704 273.395 704 190C704 106.605 636.395 39 553 39C469.605 39 402 106.605 402 190C402 273.395 469.605 341 553 341Z" stroke="black" stroke-width="2"/>
|
||||
</g>
|
||||
<g filter="url(#filter7_d)">
|
||||
<path d="M545.045 205.97L530.011 190.925L525 195.94L545.045 216L588 173.015L582.989 168L545.045 205.97Z" fill="#B3FF99"/>
|
||||
<path d="M545.045 204.555L530.719 190.219L530.011 189.511L529.304 190.219L524.293 195.233L523.586 195.94L524.293 196.647L544.338 216.707L545.045 217.415L545.753 216.707L588.707 173.722L589.414 173.015L588.707 172.308L583.696 167.293L582.989 166.585L582.281 167.293L545.045 204.555Z" stroke="black" stroke-width="2"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d" x="95" y="230" width="165" height="52" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset dy="4"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter1_d" x="95" y="103" width="165" height="52" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset dy="4"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter2_d" x="26" y="38" width="304" height="308" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset dy="4"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter3_d" x="28" y="40" width="300" height="304" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset dy="4"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter4_d" x="470" y="230" width="165" height="52" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset dy="4"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter5_d" x="470" y="103" width="165" height="52" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset dy="4"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter6_d" x="401" y="38" width="304" height="308" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset dy="4"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter7_d" x="522.173" y="165.171" width="68.6548" height="57.6589" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset dy="4"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 23 KiB |
146
content/blog/master-react-unidirectional-data-flow/index.md
Normal file
146
content/blog/master-react-unidirectional-data-flow/index.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
{
|
||||
title: "Master React Unidirectional Data Flow",
|
||||
description: "",
|
||||
published: '2021-04-27T22:12:03.284Z',
|
||||
authors: ['crutchcorn'],
|
||||
tags: ['react', 'javascript'],
|
||||
attached: [],
|
||||
license: 'coderpad',
|
||||
originalLink: 'https://coderpad.io/blog/master-react-unidirectional-data-flow/'
|
||||
}
|
||||
---
|
||||
|
||||
As with any form of programming, there are dozens of ways to manage data inside a React application. That said, not all methods are equally capable of scaling. There are some "suggested patterns" for your React applications to follow that will ensure you're not forced to pause in order to reorganize or re-evaluate your existing code when you’re building the application.
|
||||
|
||||
Today, we'll be covering one of the most important structural best practices to follow when building your React applications: Unidirectional data flow.
|
||||
|
||||
## What is Unidirectional Data Flow?
|
||||
|
||||
Unidirectional data flow is the idea that components should only raise data in one direction. Child components should only call functions from parent components, while parent components should only set/pass data to their children.
|
||||
|
||||

|
||||
|
||||
In order to explain how both of these look in real code, let's start with how a properly unidirectional parent and child component would be written.
|
||||
|
||||
## Unidirectional Demo
|
||||
|
||||
A great example of a set of components we'll use to demonstrate unidirectionality is a parent "App" component and a child "Form" component.
|
||||
|
||||
Let's take a look at a code sample that follows this unidirectionality first:
|
||||
|
||||
<iframe src="https://app.coderpad.io/sandbox?question_id=176771" width="640" height="480" loading="lazy"></iframe>
|
||||
|
||||
As you can see we're passing the `onChange` and value props to `SimpleForm`. This keeps our state consolidated inside of the `App` component rather than split between `App` and `SimpleForm`. Once you "submit" the form, `SimpleForm` calls `onDone` which changes the state stored inside of `App`. This in turn causes a re-render of `SimpleForm`.
|
||||
|
||||
While `SimpleForm` is displaying the data to the user, the logic itself stays within `App`. `SimpleForm` contains no state or application logic; we call components like these "dumb" components. "Dumb" components are utilized for styling and composability, but not for app logic or state.
|
||||
|
||||
This is what a set of proper React components *should* look like. This pattern of raising state out of the component itself and leaving "dumb" component comes from the guidance of the React team itself. This pattern is called[ "lifting state up"](https://reactjs.org/docs/lifting-state-up.html).
|
||||
|
||||
Now that we have a better understanding of the patterns to follow let's take a look at the wrong way to do things.
|
||||
|
||||
## Breaking from Suggested Patterns
|
||||
|
||||
Now that we've "lifted" the state, let's drop back down into `SimpleForm`. We'll start by changing `SimpleForm` to a class component and adding state.
|
||||
|
||||
```jsx
|
||||
class SimpleForm extends React.Component {
|
||||
// State is now a part of the SimpleForm component
|
||||
state = {
|
||||
input: ""
|
||||
}
|
||||
|
||||
onChange(e) {
|
||||
this.setState({
|
||||
input: e.target.value
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<label>
|
||||
<div>Username</div>
|
||||
<input onChange={this.onChange.bind(this)} value={this.state.input}/>
|
||||
</label>
|
||||
<button onClick={this.props.onDone}>Submit</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now, we can use ref in `App` to access the class methods and state.
|
||||
|
||||
```jsx
|
||||
export default function App() {
|
||||
const simpleRef = React.useRef()
|
||||
const [displayTxt, setDisplayTxt] = React.useState("")
|
||||
|
||||
const onDone = () => {
|
||||
// Reach into the Ref to access the state of the component instance
|
||||
setDisplayTxt(simpleRef.current.state.input)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<SimpleForm
|
||||
onDone={onDone}
|
||||
ref={simpleRef}
|
||||
/>
|
||||
<p>{displayTxt}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
<iframe src="https://app.coderpad.io/sandbox?question_id=176773" width="640" height="480" loading="lazy"></iframe>
|
||||
|
||||
This code works, but has some inherent complexity issues. When you start expanding this component, this idea of separating your state and having to inspect the child reference from the parent makes development more difficult. Let's take a look visually how following the application logic is now more difficult with this pattern.
|
||||
|
||||
## Visualizing the Problem
|
||||
|
||||
First, let's start by taking a look at the `simpleRef` component, where the state is "lowered down" to the `SimpleForm` component:
|
||||
|
||||

|
||||
|
||||
In this example, the flow of the application state is as follows:
|
||||
|
||||
- `App` (and its children, `SimpleForm`) render
|
||||
- The user makes changes to the data stored in `SimpleForm`
|
||||
- The user triggers the `onDone` action, which triggers a function in `App`
|
||||
- The `App` `onDone` method inspects the data from `SimpleForm`
|
||||
- Once the data is returned to `App`, it changes its own data, thus triggering a re-render of `App` and `SimpleForm` both
|
||||
|
||||
As you can see from the chart above and the outline of the data flow, one action goes back and forth between the parent and child as `App` attempts to access the data stored in `SimpleForm`. This is a prime example of a bi-directional component action. This code sample gets even more complex when onDone is expected to change the state in SimpleForm.
|
||||
|
||||
Now, let's contrast that to the mental model needed to work with unidirectionality enforced.
|
||||
|
||||

|
||||
|
||||
- App (and its children, `SimpleForm`) render
|
||||
- The user makes changes in `SimpleForm`, the state is raised up to `App` through callbacks
|
||||
- The user triggers the `onDone` action, which triggers a function in App
|
||||
- The `App` `onDone` method already contains all of the data it needs in it's own component, so it simply re-renders `App` and `SimpleForm` without any additional logic overhead
|
||||
|
||||
As you can see, while the number of steps is similar between these methods (but may not be in a less trivial example), the unidirectional flow is much more streamlined and easier to follow.
|
||||
|
||||
This is why the React core team (and the community at large) strongly suggests you use unidirectionality as often as possible.
|
||||
|
||||
## Conclusion & Challenge
|
||||
|
||||
Understanding unidirectionality is integral to scaffolding scalable React applications. Unidirectionality doesn't just apply to React, either - Angular and Vue applications often require similar patterns for large scale codebases to be easier to follow and more performant.
|
||||
|
||||
Now that we have a deeper understanding of unidirectionality, here's a challenge for you: Refactor the following components to better reflect unidirectionality in this coding pad.
|
||||
|
||||
<iframe src="https://app.coderpad.io/sandbox?question_id=176774" width="640" height="480" loading="lazy"></iframe>
|
||||
|
||||
The functionality of the app should be consistent with the previous version. Stuck?
|
||||
|
||||
Start with:
|
||||
|
||||
- Move the `getNewActivity` into a `React.useEffect` in App
|
||||
- Move the `state.activity` into a `React.useState` in App
|
||||
- Pass all props to `DisplayActivities`, making it a "dumb" component
|
||||
|
||||
Still stuck? Maybe you're excited to share your solution?[ Send us a Tweet @CoderPad](https://twitter.com/CoderPad) or[ ask us in our community Slack](https://bit.ly/coderpad-slack). We'd be excited to hear from you!
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 79 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 72 KiB |
Reference in New Issue
Block a user