I follow the approach of creating libraries for cases like this in my applications, and so far this works pretty well for me.
In this case, I would create a new module, e.g. {ComponentRoot}/lib/user.js which exports a function getFullName(user) or possibly getFullName(firstName, lastName, country), depending the circumstances.
Now it is just a matter of importing the module where you require the functionality, no global functions needed:
import React from 'react'
import {getFullName} from '../lib/user'
const Title = ({user}) =>
<div>
{getFullName(user)}
</div>
We place our library folder on the same level as the components folder etc., but whatever works best for you should do.
Answer from TimoStaudinger on Stack OverflowWhere to put utility functions in a React-Redux application?
reactjs - Correct way to share functions between components in React - Stack Overflow
Global utility functions in react? How to implement
refactoring - ReactJS hook vs utility function - Software Engineering Stack Exchange
Videos
I follow the approach of creating libraries for cases like this in my applications, and so far this works pretty well for me.
In this case, I would create a new module, e.g. {ComponentRoot}/lib/user.js which exports a function getFullName(user) or possibly getFullName(firstName, lastName, country), depending the circumstances.
Now it is just a matter of importing the module where you require the functionality, no global functions needed:
import React from 'react'
import {getFullName} from '../lib/user'
const Title = ({user}) =>
<div>
{getFullName(user)}
</div>
We place our library folder on the same level as the components folder etc., but whatever works best for you should do.
First of all, Redux has no opinion on the file structure of your application.
Some famous boilerplate projects put the code into a utils/ folder:
- react-boilerplate
- react-redux-universal-hot-example
- react-slingshot
- electron-react-boilerplate
Sample folder structure:
src/
components/
...
reducers/
...
utils/
...
Utils.js with latest Javascript ES6 syntax
Create the Utils.js file like this with multiple functions, etc
const someCommonValues = ['common', 'values'];
export const doSomethingWithInput = (theInput) => {
//Do something with the input
return theInput;
};
export const justAnAlert = () => {
alert('hello');
};
Then in your components that you want to use the util functions, import the specific functions that are needed. You don't have to import everything
import {doSomethingWithInput, justAnAlert} from './path/to/Utils.js'
And then use these functions within the component like this:
justAnAlert();
<p>{doSomethingWithInput('hello')}</p>
If you use something like browserify then you can have an external file i.e util.js that exports some utility functions.
var doSomething = function(num) {
return num + 1;
}
exports.doSomething = doSomething;
Then require it as needed
var doSomething = require('./util.js').doSomething;
So, first of all, your assumption that multiple imports means multiple script executions is probably not true. I just tried it in Node JS and it seems like the re-imported modules were not ran again.
However, you can avoid multiple resource requests by caching the result in a service module. Here's a simple example on stackblitz. The service module only contains a function getData which returns either a promise issuing a request (which also caches the received data) or directly resolves to cached data (if they exist).
// log this everytime the script is being executed
console.log('get-data.js module being executed');
// just an example
const resourceUrl = 'https://raw.githubusercontent.com/bahamas10/css-color-names/master/css-color-names.json';
let cachedData = null;
const getData = () => {
if (cachedData === null) {
console.log('get-data: requesting data');
return fetch(resourceUrl, {})
.then(response => {
cachedData = response.json();
return cachedData;
});
} else {
console.log('get-data: returning cached data');
return Promise.resolve(cachedData);
}
};
export { getData };
In the example, getData is getting executed in an interval every 5s. As you can see though from the log statements only the first call results in a request for fresh data; otherwise the cached data are being served.
I'm also importing getData twice (once in "index.js" and once in "header.js") but the console.log statement in "get-data.j" is only getting executed once. So it's very likely not being executed again after the first import.
If you want to get more fancy, there are a couple of other—arguably more complicated—ways to implement a "global" utility function. For example:
- Redux middleware, Redux async middleware
- Dependency injection
I suggest keeping your messages in the context and create a component to retrieve the messages from the react context. You can also create a object with the "global" function and inject it with a HOC.
The way I do it is I have a component that uses the react context to retrieve a message using the messages object and current locale to display it in the rendered output. I also created a HOC which injects some helper functions for retrieving messages for placeholders ect.
I noticed I have many components that have functions that are relevant only to them, so I avoided placing these functions in my general services/utilities folders. However sometimes a component of mine will have many functions that are specific to it, and so the file of the component becomes quite long (eg I have a file with 500 lines). I was wondering what is the common way amongst developers of structuring these types of functions or even consts that are related only to a specific component, should I extract them to different files inside the component folder or just leave them in the original file?
I have what is essentially a CRUD application with a dashboard component.
The user can create / delete new items on that dashboard.
I have a lot of functions in my dashboard component related to the crud operations (e.g. opening dialogue boxes, adding/removing items, selecting an item etc...) and there are about 170 lines of code dedicated to those operations across different functions.
I've Googled some solutions and it looks like I could store these functions in a utility file and import them to the dashboard component, which would make the dashboard component a lot cleaner.
Is this best practice? While there are a lot of lines of code, they are still generally related to the operations I want to be able to do on the dashboard.