I'm a React newbie trying to integrate React into a Rails site. I have a CommentForm component at the very top of the page/html, and a Comments component at the bottom of the same page. At present, both are rendered through React-On-Rails' react_component method.
The problem is that, upon submitting a form in CommentForm, I'd like to change this.state.comments in the Comments component. I'm familiar with the idea of ensuring state is bubbled up to a common parent component, but at present, these two components don't have a common parent (or any parents at all).
So, with the disclaimer that I've been learning React for all of 2 days and am likely very confused, what's best practice for overcoming this sort of issue? Options as I see them:
Rewrite the entire rails view as a single parent component with the two components as children underneath. This doesn't sound fun - there's a lot of html generated by a lot of rails helpers between the two components on the page
Use Redux to create a store that's shared between the two components(???)
Somehow create a parent component while still rendering the two other components in separate parts of the page(?)
Accessing Comment's state attributes from within CommentForm or some shared resource (eg: window scope), which, from my limited understanding, isn't the React Way
I'm guessing this is a common problem, but I'm uncertain what the general wisdom is to fix it. Any ideas appreciated.
The first option would be doing the react way only (with no external libraries). If your project it's not that big, could be a solution.
The third and fourth option are definitely not the way to go.
For what you said, using Redux seems to be the easiest solution.
The Comments component should be drawing all the comments in your global store and the CommentForm should add the comments to the store (and probably send an AJAX request for saving server side also).
Then, these components will share the same Provider and have access to same Store.
I'd suggest you watching Dan's Course
Redux is the perfect use case for this honestly. It doesn't take too long to implement but if you've never done it before you're gonna need a day or two to wrap your head around it.
In general, as your project grows even more, you will have a much easier time managing one state instead of a thousand component wide states.
So, if you're gonna have more situations like this, or situations where you have to pass down props through more than 3 components. I'd implement Redux now and be future proof.
Related
I'm trying to achieve a relatively easy goal: create a simple cross-platform CRM app to manage contacts/customers and their relations with companies. At the current state I'm fairly confused on how to approach this (after some early motivational success).
After half a year of Objective-C and iOS development under my belt I wanted to get more serious and start on a real app project, which would be the mentioned CRM app. Then I heard about PhoneGap, tried it out and was very impressed. From there on it was clear to me that my app should be cross-platform.
To have a better understanding of what I'm trying to achieve, here are some details about the "requirements":
Simple data model, 5 or 6 entities total. One-to-Many and Many-to-Many relationships.
Have a tab-bar widget to quickly toggle between companies, clients, etc.
search-as-you-type on listviews
master-detail view behavior for listviews
back buttons on the header, "add/edit" buttons as well. Classical app layout as you would expect.
My first steps lead me to JQuery Mobile for the UI which, at first glance, looked like the perfect candidate to quickly build a UI that fits the requirements and takes off a lot of coding from my hands. The mockup I created worked great on all devices, but then I hit a roadblock: the master=detail view navigation/routing. I had no clue how it's supposed to work and the JQuery Mobile docs don't supply an answer or best-practice for that. I figured out that I might be able to just pass an "id" in a querystring and read it on the details view. That worked to some extent, but only when the page is in an external file (detailsview.html?id=3) and not just an internal one (#detailsview?id=3). And even then I experienced some odd behavior when reading the value from the querystring on the pageshow event. Anyway, all this tinkering with logic and design led me to the clue that there must be a better and more organized approach, something like MVC. And apparently there is, namely backbone.js and Angular.js (and ember.js etc.) that come with decent deep-linking. Some googling told me that Angular.js might be a better fit for me since it comes with 2-way data-binding and makes me write less code, which is always appreciated.
But then there's the problem of a functional overlap between JQuery Mobile and Angular.js since JQuery Mobile has it's own routing capabilities. I could disable that part I guess, but I would probably lose the page transitions in the process (no more "pages" in the index.html)? I found topcoat as an alternative for the UI but it currently lacks a much needed/wanted tab-bar widget as it seems. Just as Twitter Bootstrap which seems to lack it as well.
And I haven't even touched persistent storage yet! The PhoneGap API provides storage capabilities but after some years with nice ORM implementations like Hibernate, Entity Framework and Core Data I want something more "natural" than pure SQL. On the other hand, pure SQL might be doable since the scope of the project is somewhat limited. So I came across JayData but have't tried it yet. Since Angular.js seems to prefer data input in JSON format, maybe Lawnchair.js might be a good idea? I looked into it but I couldn't quickly find out how to reference relations and/or objects in a traditional way. My learning curve aside, is lawnchair.js a good way at all to store relational data? Or CouchDB from a server perspective? Most of the examples I found only stored non-related data or contained arrays not referencing other objects. I guess all it needs is storing the object identifiers in those arrays, but how to do auto-create, auto-increment them and make sure that they're unique?
I would greatly appreciate your thoughts, comments and a little guidance on this :)!
Thanks a lot!
During the last weeks I was playing around with a bunch of storage and UI solutions, the ones that I settled with are lawnchair.js, JQuery Mobile and some other things like Handlebars.js for templating. They are fairly simple to use and exactly what I needed.
To store my JSONs I created Lawnchairs like this:
var clients = new Lawnchair({
name: 'clients'
}, function (store) {
// I don't really need the callback here
});
Lawnchair's JSON based storage makes it simple and intuitive to store your data directly in your javascript code with a single line:
clients.save({firstName: "Jason", lastName: "Bourne", ...});
This will also fully automagically create a unique key for you to access the object later. Big bonus that wasn't mentioned anywhere! You could create and define your own key, but for my purpose the auto-generated one fits perfect.
To create realtionships with your other Lawnchairs, like "companies", you could add the key to the querystring, read it on the detailspage, and add the key to the company's property you want, like:
myJSONclient = clients.get(SuperLongAutoGeneratedKeyReadFromAueryString);
// Probably do some stuff with the object
// Add the key to the current company object
currentCompany.bestCustomer = myJSONclient.key;
// save it
companies.save(currentCompany);
That's all there is to it :)!
I am just starting a project and the wireframes are ready. But looking at the wireframes it seems that the primary goal was to reduce the number of pages and to include maximum functionality in to a single page.
Taking an example of an organization, the top portion of the page will show the organization details, below that at the left we have an division structure as a tree view, clicking on a division will populate the employee list on the right as a table, and when you click on an employee it will populate the employee details below.
Current wireframe looks something like this:
End user is happy as they can see the entire functionality on a single page and doesn't need to navigate to another page.
But this design reminds me the screen of some old desktop application and I feel that this page is unnecessarily complex- I want to split this in to multiple pages (at least in to three). Also, I am using MVC 4 and splitting this in to multiple pages will definitely help me to reduce the complexities during implementation.
But before arriving at any conclusion and raising any concern, I would like to know what you guys think. Some articles related to User experience are also welcome.
Here's what I think.
Whether the design above is 'right' depends on the target audience and the type of work / business process they need to carry out. There may be a strong business argument for being able to see all the information (org details, divisions, employees and employee details) on one page. It is not unusual to see a lot of information displayed in a page with a lot of interactivity - users expectations have increased because of consumer sites such as Gmail.
The users might find it frustrating if it was broken out into different pages.
To put it another way, I don't think there is a valid technical justification for making the designer change the UI above to split it into different pages.
You would be able to build the UI above in MVC as a single page web application. You will probably need to implement a lot of controller actions to support ajax calls. You're almost certainly going to end up using a lot of JQuery and you are probably also going to end up with a significant amount of JavaScript to write. Also, you'll need to make sure the designer has made good decisions around the sizing of the page. Is it going to be fixed width or dynamic for instance? You'll need to emit well structured HTML in order to achieve that solely using CSS (which I would strongly advise you do).
I'm working on building a mobile application for a client using jQuery Mobile. The question I have is fairly basic and non-technical:
The application can have three different types of users, all with a different menu layout. Some users will have access to some parts of the system that other users will not.
My question is- should I hardcode the menu system in the index.html file or should I dynamically create it when they log in? I'm assuming that there would be a slight performance gain by hardcoding the menu and then just choosing which #page to display as opposed to requiring an ajax call...but keeping the menu builder on the server side processing keeps us more agile if need to change the menu after deployment.
Deep apologies if this has already been asked. Thanks for your help!
Build your pages dynamically. On jQuery mobile, a lot of stuff will be repeated and if you want to respect the DRY principle and want to create easily maintainable code, do it dynamically.
Also, by doing this on a mobile application you will reduce the loading times : instead of loading 3 pages you'll only load one, wich can be crucial in mobile developpement.
Hard coding is bad if it can be done dynamically do it because it saves over head and produces nicer code that is easier maintainable.
If you want to change the menu in the future you can just edit the source of information instead of going through all your code having tons of messy if and else statements saying if this person is logged in don't show this option but show this one etc.
I am a little ashamed for asking so many questions, but I really want to learn.
In Sipke's blog a webshop is created. There is one specific question that boggles my mind when trying to do something similar.
Let me spell out the basic requirements:
User registration form and login, etc. This one is covered by the blog and it works nice.
Creating product parts and so on. This one is covered and no problem there.
Ordering by filling in an order form and making the payment. See down
Having the order page maintainable by customer. See down.
Viewing your own orders and their status. See down
Maintaining customers and orders from backend system. This one is covered by the blog and I need to do some work there yet.
As for items regarding creating orders and viewing your orders. I have followed the approach for creating records and using standard MVC controllers. But then I encountered problems:
Menu for orders page. This I had to do manually after installing the module.
The order page itself. I had to create the view including title and so on. But I can imagine a customer wanting the order page on another menu and with a different title. And maybe add even some own content to the ordering page. This I couldn't achieve by using standard MVC approach. So maybe I am using the wrong approach here. So I was thinking about using contentparts for creating an order and displaying them and using the drivers and handlers for that. But before I go down that road and refactor everything I want to know if that is the right approach. A downside could be that once the module follows that route it can then not so easily be reused with customers that have other cms's capable of hosting an MVC3 module.
So when to use drivers, handlers and contentparts and when to use standard controllers and views.
You should use Drivers and Parts (with Handlers if needed) when you want to create functionality for content items. E.g. if you want to display a custom media with all products, you could create a Part (together with its Driver, etc.) to handle that. Read the docs on Parts.
If the functionality is not tied to content items the most possibly you want to use the standard MVC toolbox, it's fine. Look at the built-in modules how they do that. E.g. the Blog module uses controllers and views to show the admin UI, but has parts to enhance the functionality of for example the Blog content type.
To make things more complicated you can employ ad-hoc content items to build a page that you'd normally do with simple views, but that's an advanced topic :-).
I'm wondering what you think of the several methods there are to accomplish this:
Use symlinks for the shared files
Create a gem/plugin that provides the shared files and code
Create a web service that pulls views/partials from the required app and stores it in a cache
My objective is to reduce complexity in a large application. Let's say I want to build an online community, and I want one app to handle forums, another to handle user galleries, etc., and a central one which manages users and provides common views to the other apps.
So, the master application would have to provide a common layout and widgets to all others, and each app would need to provide some views to the master app too.
For example, say the layout has a main menu with an item for each app, and each item has an over-sized sub-menu, so I can't just have a simple list of label and URL pairs.
So perhaps the master app would ask each child app to provide its menu item and contents through a private API, build the menu, save the output in a cache, and send the full menu to each app when asked.
As you can see, I'm already leaning towards option 3, but I wanted some feedback on my approach and if maybe there's a better way.
Thanks for your input.
From what you describe it really sounds like you should be using a single Rails application. The view interdependency makes me think that you might benefit from this approach. I also imagine that testing will be more difficult because your 'application' will span three actual Rails applications.
That said, if you are set on using three applications, I would recommend against using and API. APIs are great for passing data (json, xml...) back and forth, but they aren't as well suited to views. My recommendation would be to create a plugin of common views that could be stored in a separate git repository and simply used within each of your applications. That way the common code is shared amongst the applications yet still locally accessible to all of them.