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 AĀ 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.

I’ve been working on my form component and here it is:Ā https://github.com/unodgs/react-semanticui-forms. Of course this is still work in progress and it’s missing few essential parts like select tag or better form definition errors handling but I’m already using it in my apps so why not you ;). Below screenshot from example app (from github repo):

reactjs-sematnticui-forms

Since the last time I made following changes:

  • ref is no longer needed in Submit declaration
  • data property was changed to dataFn. Now it points to this.dataFn (that comes from FormMixin). Unfortunately there is no (known to me) way of making it unnecessary (provided implicitly by Form component). But I can live with that – I hope future versions of react will make it possible.
  • dataFn must be provided in every component (including Form)

This is the code of the form from the screenshot:

For now my form component is strictly connected with semantic ui css framework but I’m working on make it css independent. I hope you’ll find it useful. I’m aware of others similar components but none of them fits my needs. What I was missing the most was inability to freely mix form inputs with form layout. See you soon.

As you probably already know React is quite a new gamer in SPA world. In contrast to AngularJS it prefers functional approach to deal with complex and interactive UI. After creating two projects with Angular I decided to try it out with my new application. I will describe overall impression later, here I want to share my problems with form component.

My application consists of many forms like settings, user profile, registration panel etc. Each of them:

  • has input elements and submit button
  • loads initial data via ajax
  • stores entered data via ajax
  • blocks form during ajax calls
  • has nice progress indicator

I could create each of those form in classical way described in react documentation but that would be cumbersome and generated too much code. This is what I wanted to achieve:

Every kind of html input is wrapped in a react component that stores input type, its value and other necessary parameters as well as internal state if component is a little bit complex. Then Form component iterates over its children, creates validation rules for validation plugin (which in my case comes from http://semantic-ui.com) and responds to submit button. Form component is also responsible for loading and saving form data from url passed through url attribute.

I was really surprised that such a functionality is impossible to achieve in react (at least in current version). Of course that might be my fault and I would be thankful if someone shared a similar component that is working. So what is the problem? The problem is parent – children communication. Let’s take a look at a Form component (simplified version):

The most interesting part is {this.props.children}. In this property all the tags between <Form></Form> declared in PersonalDataForm are passed. One can iterate over them using React built in functions. Here’s my iteration helper (react’s foreach looks for children only one level deep in dom hierarchy):

Unfortunately (in this case) Form component is not the owner of those children. The PeronalDataForm is. That has consequences. I can’t in Form update the children properties or transfer properties passed to Form (it’s a problem because this is the preferred way of communicating with children in react). Also if I would like to modify state of children I’m forced to use undocumented internals of react (that can change in feature versions) like __realComponentInstance (if that only worked šŸ™‚ , the render method of child component still used previous state). What worked in the code above was validation as reading data from this.props.children was perfectly fine. What didn’t work was modifying props or state of children. I wasn’t able to load data from server and distribute it among childrenĀ from within Form component.

I hope in future version communicating between children and parent will be addressed in some way or another. In the meantime I used mixins. Now PersonalDataForm looks like this:

I simply inlined all the methods that previously were placed in the Form component into the PersonalDataForm. Now PersonalDataForm is the owner of all inputs and is able to manipulate them. I also gave up on iterating over children through this.props.children. Now I iterate over this.refs. That simplifies the code but requires providing ref attribute at every input wrapper. Another disadvantage is forcing user to mix in FormMixin in every form component and unnecessary code duplication because of that. User also has to pass this.state.data (which contains ajax data) everywhere, but the final effect is very similarĀ to what I really wanted. I will post sources of my components soon.