React is a library that is generally used just as the “view” or “presentation” layer of our applications. That means it is not a typical MVC application. But we have a lot of flexibility around how we structure our React SharePoint Framework Projects. And in some cases it might make sense to organize our projects in a way that resembles the MVC pattern. This post will cover some possible ways of structuring SPFx projects that use React.
Everything in One File
If your web part does not have any interaction with any kind of persistence layer (such as SharePoint, Graph API, OneDrive), and does not implement extensive business logic, you could structure it with all of your application layers in the webpart.tsx file. It could look something like this.
Separate Business Logic and View
If you need of a separate layer for business logic, you could structure it similar to the following. In this case, there is no persisted data to interact with. However, there is still a ‘separation of concerns’ between the TypeScript file that holds the business logic and the TSX files that create the view.
Separate Files for Properties, Data Communication, Business Logic, and Presentation
If you need to communicate with a data source, such as a SharePoint or OneDrive web service, you can make those calls in the business logic (controller) layer. These can just be ordinary TypeScript files, since there is no view. These files communicate with the model (data). They can also define (and transform) the structure of the data using interfaces (highly recommended!)
Here is an example of an interface that I used for our search results:
This is really powerful, not only for type-ahead, but also for mapping items from a search to a strongly typed data object — as shown in the example below.
Notice in the example above, that TypeScript is able to convert all results from a search to objects that implement the IWorkforceSearchResult interface. This allows me to set a variable called ‘newTitle’ to the strongly typed attribute of the searchresult object.
Moving on to the view. All the classes in my project extend the React.Component class. However, only the ‘view’ layer files need to be in .tsx format. In my example below, the presentation layer classes have a unique way of displaying the different types of search results, such as People, Files, Catalog, etc. that are contained in different .tsx files.
For example, the Person results are displayed using the Person.tsx class. In this case we are using UI Fabric’s ‘Persona’ control.
Where the Catalog results use the Catalog.tsx class, defined as follows…
Communicating from parent to child components
Communication between parent and children layers should be done through properties. When you are passing properties from a parent to a child component, it is as easy as adding them to the child declaration in the parent component. In the following case, we are passing siteUrl, context, items, and searchType to the child.
Passing data from a child component to a parent component is more complicated, and will be the topic of a future post.