Learn more about our current job openings and benefits of working at FSL.
Detailed reviews and feedback from past and current clients.
Get to know the Management Team behind FullStack Labs.
Our step-by-step process for designing and developing new applications.
Writings from our team on technology, design, and business.
Get answers to the questions most frequently asked by new clients.
Learn about our company culture and defining principles.
A high level overview of FullStack Labs, who we are, and what we do.
A JavaScript framework that allows rapid development of native Android and IOS apps.
A JavaScript framework maintained by Facebook that's ideal for building complex, modern user interfaces within single page web apps.
A server side programming language known for its ease of use and speed of development.
A lightweight and efficient backend javascript framework for web apps.
An interpreted high-level programming language great for general purpose programming.
A JavaScript framework maintained by Google that addresses many of the challenges encountered when building single-page apps.
A JavaScript framework that allows developers to build large, complex, scalable single-page web applications.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A progressive JavaScript framework known for its approachability, versatility, and performance.
View a sampling of our work implemented using a variety of our favorite technologies.
View examples of the process we use to build custom software solutions for our clients.
View projects implemented using this javascript framework ideal for building complex, modern user interfaces within single page web apps.
View projects implemented using this framework that allows rapid development of native Android and IOS apps.
View projects implemented using this backend javascript framework for web apps.
View projects implemented using this high-level programming language great for general purpose programming.
View projects implemented using this server side programming language known for its ease of use and speed of development.
We have vast experience crafting healthcare software development solutions, including UI/UX Design, Application Development, Legacy Healthcare Systems, and Team Augmentation. Our development services help the healthcare industry by enhancing accessibility, productivity, portability, and scalability.
We offer a range of custom software development solutions for education companies of all sizes. We're experts in Education Software Development and specialists in enhancing the learning experience across web, mobile, and conversational UI.
We're experts in developing Custom Software Solutions for the Logistics Industry. Our work offered a whole new and more efficient way for Logistics companies to manage their crucial operations.
We partner with various construction industry organizations to build custom software development solutions. Our Construction Software Development Services allow construction companies to manage projects, resources, and documentation.
We have vast experience crafting healthcare software development solutions, including UI/UX Design, Application Development, Legacy Healthcare Systems, and Team Augmentation. Our development services help the healthcare industry by enhancing accessibility, productivity, portability, and scalability.
We offer a range of custom software development solutions for education companies of all sizes. We're experts in Education Software Development and specialists in enhancing the learning experience across web, mobile, and conversational UI.
We're experts in developing Custom Software Solutions for the Logistics Industry. Our work offered a whole new and more efficient way for Logistics companies to manage their crucial operations.
We partner with various construction industry organizations to build custom software development solutions. Our Construction Software Development Services allow construction companies to manage projects, resources, and documentation.
Learn more about our current job openings and benefits of working at FSL.
Detailed reviews and feedback from past and current clients.
Get to know the Management Team behind FullStack Labs.
Our step-by-step process for designing and developing new applications.
Writings from our team on technology, design, and business.
Get answers to the questions most frequently asked by new clients.
Learn about our company culture and defining principles.
A high level overview of FullStack Labs, who we are, and what we do.
A JavaScript framework that allows rapid development of native Android and IOS apps.
A JavaScript framework maintained by Facebook that's ideal for building complex, modern user interfaces within single page web apps.
A server side programming language known for its ease of use and speed of development.
A lightweight and efficient backend javascript framework for web apps.
An interpreted high-level programming language great for general purpose programming.
A JavaScript framework maintained by Google that addresses many of the challenges encountered when building single-page apps.
A JavaScript framework that allows developers to build large, complex, scalable single-page web applications.
A progressive JavaScript framework known for its approachability, versatility, and performance.
A dynamic programming language used in all sorts of web and mobile applications.
A cross-platform programming language designed to run robust applications on any device.
A UI toolkit used to build natively compiled applications from a single codebase.
A functional programming language that’s ideal for scalability, maintainability, and reliability.
A Customer Relationship Management (CRM) platform that seamlessly integrates with your business operations.
A high-performance programming language that makes it easy to build simple, reliable, and efficient software.
View a sampling of our work implemented using a variety of our favorite technologies.
View examples of the process we use to build custom software solutions for our clients.
View projects implemented using this javascript framework ideal for building complex, modern user interfaces within single page web apps.
View projects implemented using this framework that allows rapid development of native Android and IOS apps.
View projects implemented using this backend javascript framework for web apps.
View projects implemented using this high-level programming language great for general purpose programming.
View projects implemented using this server side programming language known for its ease of use and speed of development.
In my last post, An Introduction to React.js Hooks, I provided a general introduction to hooks with a real world example. In this post, I’ll dive into patterns for architecting production-level React hook apps.
Unlike class components which organize all lifecycle methods into a single class, hooks distribute them into reusable functions that can be used across more than one component or file.
Initially, it is tempting to add all required hooks to the top of a giant function and return JSX at the bottom. Check out this example to-do app code below:
-- CODE language-jsx keep-markup --
import React from 'react';
import { useState, useEffect, useCallback } from 'react';
import { useNavigation } from 'react-navigation-hooks';
import { useDispatch, useSelector } from 'react-redux';
const Todos = () => {
const { setParams, getParam, navigate } = useNavigation();
const initSearch = getParam('initSearch', '');
const [searchText, setSearchText] = useState(initSearch);
const {
todos,
loading,
} = useSelector(({ todos: todosData }) => ({
todos: todosData.todos,
loading: todosData.loading,
}));
const dispatch = useDispatch();
useEffect(() => {
dispatch(getTodos());
}, [dispatch]);
/* Functions for handling data and responding to events */
onItemPressed = (item) => navigate('TODO_DETAIL', { todo })
{...}
return loading ? (
<loadingindicator> </loadingindicator>
) : (
<view></view>
value={searchText}
onChangeText={setSearchText}
/>
<list data="{todos}" onitempressed="{onItemPressed}/"></list>
);}
This method works, but it is not very readable and creates unnecessary complexity.
To clean things up, refactor each hook that accesses data into a custom hook in a separate file.
-- CODE language-jsx keep-markup --
import { useState, useEffect, useCallback } from 'react';
import { useNavigation } from 'react-navigation-hooks';
import { useDispatch, useSelector } from 'react-redux';
const useTodosHooks = () => {
const { setParams, getParam, navigate } = useNavigation();
const initSearch = getParam('initSearch', '');
const [searchText, setSearchText] = useState(initSearch);
const {
todos,
loading,
} = useSelector(({ todos: todosData }) => ({
todos: todosData.todos,
loading: todosData.loading, }));
const dispatch = useDispatch();
useEffect(() => {
dispatch(getTodos());
}, [dispatch]);
return {
state:{ searchText, setSearchText },
navigate,
todos,
loading
}
}
This provides a separation of the data and the view, but the component function is still very long, and contains a lot of business logic.
Additionally, testing with this structure is difficult. Without a class instance, state changes can only be executed by interacting with components of a view. There is no way to spy on the setters when using useState.
To address the issues above, separate the logic from the view.
-- CODE language-jsx keep-markup --
import React from 'react';
import useTodosHooks from './hooks';
import TodosScreen from './components/TodosScreen';
const Todos = () => {
const { navigate, ...screenProps } = useTodosHooks();
screenProps.onItemPressed = (item) => navigate('TODO_DETAIL', { todo })
return<todosscreen {...screenprops}=""></todosscreen>
}
-- CODE language-jsx keep-markup --
import React from 'react';
Import { View } from ‘react-native;
Import Searchfield from ‘./SearchField’;
Import List from ‘./List’;
Import LoadingIndicator from ‘./LoadingIndicator;
const TodoScreen = ({ loading, searchText, setSearchText, todos, onItemPressed }) => {
return loading ? (
<loadingindicator> </loadingindicator>
) : (
<view></view>
<searchfield value="{searchText}" onchangetext="{setSearchText}"></searchfield>
<list data="{todos}" onitempressed="{onItemPressed}/"></list>
);
}
With the separation above, we have emulated the popular MVC architecture using hooks.
This is the file where state and functional hooks are defined, as shown above.
This is the rendered JSX. The props of this functional component are only the necessary state and functions for displaying and interacting with the view.
This is the initial, giant function. It now de-structures only what it needs from the model, some of which may be passed down to the view. Notice that all state and setters are wrapped in a state object for ease of transport and again being able to destructure only what is necessary.
While there are now more files, each of these three functions has a specific job and references only the data that is necessary. Each file is more readable, and therefore easier to understand and review. The code is also much easier to cover with tests. The controller can be mounted, with mocks for any library hooks, and can cover most of the three files. When state needs to be altered or a setter needs to be spied on, the view component can be mounted with mocked props inputs.
In a production-level application, the same data and logic is going to be used in several places. This provides an opportunity to eliminate repetition in the models.
A prime example is the react-redux useSelector hook. Many views will rely on the same data, which mean selectors and their getter actions wind up implemented in several models. A file can be made for a redux wrapper, and another can be made for a combination of selectors and dispatch hooks per data type.
-- CODE language-jsx keep-markup --
import { getTodos } from '../actions/todos';
exportconst useGetTodos = () => {
const dispatch = useDispatch();
const {
todos,
loading,
} = useSelector(({ todos: todosData }) => ({
todos: todosData.todos,
loading: todosData.loading,
}));
useEffect(() => {
dispatch(getTodos());
}, [dispatch]);
return {
todos,
todosLoading: loading,
};
};
Using hooks incorrectly can easily cause “unnecessary” re-renderings. Although this has become a common concern surrounding hooks, it can be mitigated by gaining a better understanding of how hooks activate based on their dependencies.
The key lies in the secondary argument in useEffect, useMemo, and useCallback. In the to-do example above, the useEffect hook depends on dispatch and is passed in as the second parameter. This means the function will not redefine dispatch on every render because the context value of dispatch does not change. Therefore, useEffect will not rerun on every render.
If the dependency wasn't present, the call to getTodos would occur on every render. This would cause an infinite render loop because the redux selector would get a new state every render and then dispatch would fire again causing another render. In the class lifecycle this would be akin to unconditionally dispatching on every componentDidUpdate or, more accurately, in the render function itself.
Forget about component lifecycles and start thinking in effects - Sebastian De Deyne
---
At FullStack Labs, we are consistently asked for ways to speed up time-to-market and improve project maintainability. We pride ourselves on our ability to push the capabilities of these cutting-edge libraries. Interested in learning more about speeding up development time on your next form project, or improving an existing codebase with forms? Contact us.
We’d love to learn more about your project.
Engagements start at $75,000.