Reputation: 3308
I am building a simple React application with the following component hierarchy structure:
--- ReqList (shows a list of Request Items)
------ ReqListHeader (A div that has list title and some buttons)
------ ReqTable (list of request items)
--------- ReqRow (one row of request)
------------ ReqItemHeader
------------ ReqItemBody
------------ ...few more components in between
--------------- ReqEditor
------------------ TextArea
The root component receives data via ajax call and calls setState(data), as per the standard docs of React, and all is well, and this works correctly. I am able to show all descendant components and their values.
However for form input (textarea), the input doesn't change. I understand that I have to implement a change handler. The thing that I am unsure about is, where to implement it?
Option I: I initially thought, I would just add a changeHandler function in its immediate owner, by calling setState() on it. But I am afraid that I am breaking the uni-directional data flow principle by introducing a state in a middle level component.
Option II: Should I pass a changeHandler callback as a property from say "ReqRow" component all the way down to ReqEditor, so that it could be bound to textArea change event?
Option III: Or should I start at the root of the hierarchy i.e. ReqList? That is because, even ReqRow receives the data from its owner and its parent and so on, since that is the entry point for data.
I am not too sure, the level of upwards propagation that I should do in this case. Most of the examples are simple ones with two level hierarchy. I am sure this can be done, but involves passing down the change handler callback all the way from to its grand child.
Is this correct, or is there any other better way?
Upvotes: 0
Views: 160
Reputation: 6538
The problem your facing is solved by using any of the Flux pattern implementations. React only provides a solution for the data rendering part, but it does not provide any clue on how to handle the data flow.
Flux is a pattern proposed by Facebook that tries to structure your app so changes in the data are manageable in a clean way.
From the Flux documentation:
All data flows through the dispatcher as a central hub. Actions are provided to the dispatcher in an action creator method, and most often originate from user interactions with the views. The dispatcher then invokes the callbacks that the stores have registered with it, dispatching actions to all stores. Within their registered callbacks, stores respond to whichever actions are relevant to the state they maintain. The stores then emit a change event to alert the controller-views that a change to the data layer has occurred. Controller-views listen for these events and retrieve data from the stores in an event handler. The controller-views call their own setState() method, causing a re-rendering of themselves and all of their descendants in the component tree.
This dense paragraph is a summary of the solution to your problem.
EDIT: You can also employ baobab, a library that offers an inmutable tree of data that emits events when some field (or its children) are updated. So each component listens to changes on the fields that it needs. There is a package for integrating it with React. I've used it and works great.
Upvotes: 1