Which component should own services in React? - javascript

I am making an app with multiple top-level pages and a menu. One of the pages loads some data from the server and displays it in a table.
Should the page that displays the table call the server when it mounts and store the data in its state, or should it accept the data in its properties?

So your question is, should a tableview own its own data or receive it from the parent?
First, if the table data is used elsewhere, then you certainly want to own them higher in the hierarchy and pass them down as props to the tableview.
If not, then it depends on your use case. If it's a generic tableview, I'd say pass the data down as props as to promote the reuse of this tableview elsewhere; If the view is already very specific to your app then don't bother: just store the data as state. Personally, if my situation is the latter, I'd check to see if the tableview is reusable and convert it into the first, thus: App -> specificTableViewDataComponent -> genericTableView. The nice thing with React's architecture is that you can do this refactoring at later time, and only if needed.

Related

Make a change in an Angular service show up in all of the components that use that service

I am building the clone of a website/app called Kualitee.com. It is a test-management tool used by QA Engineers.
In kualitee, you have multiple projects, with test cases and members. You can add, delete, and change projects and members. There is a header on top which enables you to select a project of which you want the data of i.e test cases and stuff.
the header for changing projects
The approach I used for this is as follow:
1. one service containing all the data
2. one service containing only the project selected...
The whole app uses the data found in the second service. When I make a change in a project, say add a new member, it does display that at that time. After that, if I change the project in the select at the top to another project, the component containing that member does not change, even though the project is a different one now, but as soon as I switch to another component, through routing, and back again, the changes are there.
My point is, is there any way I can add functionality where, if a parent component changes an object in service, the change reflects in a child component also using that same object in that same service, without me needing to change components or refresh.
PS. This is my first time asking something on StackOverflow, Sorry if my question is confusing.
You probably need an observable shared service to share the data between components. Here is how to achieve that: Interaction between components using a service
I think you are referred to Angular life cycle https://angular.io/guide/lifecycle-hooks

Passing values between components: Pass References vs Subjects

tl;dr: Why not pass variables by reference between components to have them work on the same data instead of using e.g. BehaviorSubjects?
I'm writing a sort of diary application in Angular 8. I have two components (Navbar and Dashboard) and a service (EntryService).
Navbar lists the entries, Dashboard provides the textarea, EntryService glues them together and communicates with the database.
While debugging the application I stumbled upon a way to communicate between the service and a component that i haven't thought of before.
By accident I passed a variable (entry: Entry) from the Dashboard by reference to the EntryService. The service saved to the database getting a unique ID back and saving this ID into the entry variable. This change immediately reflected to the Dashboard because of the 'passing by reference'.
Until now I was using Subjects to update the components on changes, but passing references around seems to be much simpler, because I want to work on the same data on both components and the service.
I've studied Angular for a while now and not read about this approach, so I'm wondering if it is a bad idea or design and if yes why?
Thanks for your answers!
Passing by reference can be handy. But as a general approach to keep the application components in sync it has some draw backs. With Subjects you can easily investigate in which places of the application the value of the Subject will be changed by checking where the Subject.next() function is being called. When you pass your object by reference to a hundred components/services it will be much more difficult to find out, which of them modify the object and more importantly when, becaue often you want to trigger other changes afterwards. When you subscribe to Subjects, you get notifications about changes and can react to them. Subjects and Subscribers are an example for an Observer/Observable pattern, it allows you to decouple your application logic. And they are much more flexible, for example you can have a Subject which can return the last x number of changes or you can debounce the changes when you track user input, you can apply filters to them etc.

Loading configurational data during page load in react app

I'm working on a React application that is connected to a few ASP.NET Core WebAPI microservices. Each of these services have different entities that are used throughout the application.
Within the complete application, there are enums and 'configurational data' that can be configured.
Imagine configurational data as just simple tables, with two fields (Id and Value).
Different entities have FK relationships to the configurational data, and/or have enum fields. I'm trying to understand how I would, in a performant way, can load the configurational data and all the used enums upfront upon page load, so that these can be used in dropdowns. I'm pretty new to React (1 month), so still learning day by day.
I've initially taken the approach of writing a custom DropDown component that accepts a WebAPI GET url, to fetch the possible values for a certain table or enum, but it's very impractical and will prove to be not so performant once there are 1000 users using the application, and all doing calls to these api's multiple times, just for some dropdowns.
So, what is the advised approach to have some sort of splash screen in React AND call APIs to cache values, that then can be used in other components?
"I've initially taken the approach of writing a custom DropDown component that accepts a WebAPI GET url"
You should not do this :)
Before I suggest a solution I want to go through a couple of important key concepts.
Firstly
The render method will always run once before you async stuff happens (like your GET).
Lifecycle methods order which will trigger the First Render : constructor => componentWillMount => render => componentDidMount.
This means that you will have to have all your data ready for render initially. Or have conditions which prevents certain jsx for being called.
Secondly
If you have dynamic content, which will be the options in your dropdown, you'll have to get it from somewhere. If it's static you can define a list locally.
If you want to save the response you could use localStorage or if you are using redux; the middleware redux-persist to persist the store.
I personally don't see the purpose though, because if the dynamic options updates you would want that to update the application state. And even 1000 simple calls like that is not expensive for the server.
If you are using redux, you should keep the options there, because then you won't have to make an GET every time you're mounting the component with the dropdown.
Suggestion:
Many ways you can do this but here is a simple solution).
keep a local state in component and initialize it for first render
this.state = {dropDownOptions: []}
Then in componentDidMount make api call:
fetch(url).then((response)=>this.setState({dropDownOptions: response}));
And lastly in your render method:
<MyDropDown options={this.state.dropDownOptions} .../>

Ember.js - How share route model-data between more routes? - Why not load data in component?

TL;DR
Embers components are just smart HTML-Templates. Why they don't fetch their data for themselves like Angular? And how I can share route models over more URLs/pages. It seems that I have to know wich components are placed on which URL and I have to make them the data available over the route models. Why is this part not in the component?
I learn at the moment Ember.js. I try at least.
At the moment I have a strong problem to understand why Ember.js acts like it does. Please correct me if I am wrong at some statements. I am an Ember.js beginner. So maybe its not right what I point out here.
Lets say we have a Request on / then Ember tries to find a route model in app/routes/index.js this file contains the code which data I want to fetch from the backend. Next Ember will render app/templates/index.hbs in this file I have a component called car-list.
As far no problems but let us have a closer look. For me it feels very weird that I have to fetch at first the data by myself, why the component doesn't do this on its own? Next problem is then how can I share the model fetch logic between more routes? Maybe I want to place my component on many URLs/pages/routes then I have to copy the route model logic?
In my opinion, the component should fetch the data by itself, that you can easily insert the component on other pages without copy the whole route model fetch logic.
So I have to know wich components are placed on which URL and I have to make them the data available over the route models. Why is this part not in the component?
So maybe I am just not good enough with Ember and I just overlook something?
Components are very flexible. Components have made to be reusable. For example you can create a table component and use for cars, ships, etc.
So for reusability it's better you separate model providing from component.
But if you want to make a component which is for current project and need to fetch its data itself, you can fetch data in the component.
In some scenarios you might want to fetch data in routes. For example in your page you have multiple components and every component needs a projection of data model which fetched in route.
So it depends on your requirements, maybe you need to fetch data in component or in route or even both (mixed)
Components certainly can load their own data, and in many cases that is appropriate. But allowing the route to load the data has several important benefits that you get "for free" if you stick to that pattern:
your application's URL will always reflect the state of the data. You don't have to remember to synchronize it (in both directions -- changes to URL should change the data, and changing the data should change the URL).
you can write your templates knowing that they won't render until the data is present, allowing Ember to handle the asynchrony for you. This results in cleaner, simpler templates.
you get Ember's built-in error handling for when the data fails to load.
A username component that appears on many pages typically belongs fairly high in the route hierarchy anyway, like in the application template, where it's easy to load & render it once from a single place and have it remain visible on every child route.
But if you do need to use a component in many places and its data should be self-contained, it's fine to let it do its own loading. In that case you can either rely on Ember Data's store to give you cached responses (so you only trigger a network request the first time) or write a Service that handles some persistent state for your component.

Flux: should not-top-level views be "dump" (do not fetch data from stores)

Maybe at official flux website I saw a video were mentor said something like:
Only top-level React views should know about stores. All not top level
views should be dump and receive all information as properties.
Question: Is that right? Your argumentation, please
BUT, suppose you have some small React view Button.react that's reused on multiple pages. And suppose Button.react must know about some store data. If we won't fetch all data directly from the Button.react, we get a duplication of code at each top-level component which reuse Button.react. Is that ok for you?
I hope I am understanding your question.
One of the characteristics of React is its one-way data flow. Each component can be used by another component, just like one function can call another function. Just like a function, a React component should typically be able to get all the info it needs to do work (render itself) from the arguments passed into it. This is the function of props in React. When using Flux, sometimes the React Components, which are typically near the top of the view hierarchy, that actually fetch the data from the stores to pass down thru the application are called Controller-Views.
It is not an enforceable rule that every component doesn't become a Controller-View, getting its own state directly from a store, but it is a general practice for good reason. consider the two functions:
function renderToggleButton( isSelected ){
//... render the button
}
vs
function renderToggleButton(){
var isSelected = StateStore.getButtonSelectedState( id );
//... render the button
}
I think you will agree that the second function is more complicated and difficult to test. It has to know from where it is getting it's initial conditions. It also has to know how to identify itself in the context of the application. These are two things the function should not have to know.
Now imagine an application full of functions like this. If one function is misbehaving, it becomes very difficult to trace its inputs; to test it under controlled conditions. I hope that clarifies the guidance given for passing data thru the application as props.

Categories

Resources