Helper functions should not depend on the context of the component they are called to (at least in my opinion). If you need to use some parameter in your function passing that to function is always a better practice since it helps on re-usability. The key for the state property might be different for all components and this might lead to errors if you forget to use exact key for the state property.
For Example
export function passwordValidation(password) {
const length = password.length;
if (length > 7) return 'success';
else if (length > 4) return 'warning';
else if (length > 0) return 'error';
}
If I change function like above I can use all the given examples below.
import { passwordValidation } from '/path/to/helper/functions.js';
console.log(passwordValidation(this.state.password));
console.log(passwordValidation(this.state.confirmPassword));
console.log(passwordValidation(this.props.password));
console.log(passwordValidation(someFetchedObject.user.password));
Answer from bennygenel on Stack OverflowHelper functions should not depend on the context of the component they are called to (at least in my opinion). If you need to use some parameter in your function passing that to function is always a better practice since it helps on re-usability. The key for the state property might be different for all components and this might lead to errors if you forget to use exact key for the state property.
For Example
export function passwordValidation(password) {
const length = password.length;
if (length > 7) return 'success';
else if (length > 4) return 'warning';
else if (length > 0) return 'error';
}
If I change function like above I can use all the given examples below.
import { passwordValidation } from '/path/to/helper/functions.js';
console.log(passwordValidation(this.state.password));
console.log(passwordValidation(this.state.confirmPassword));
console.log(passwordValidation(this.props.password));
console.log(passwordValidation(someFetchedObject.user.password));
Your import and export are fine. Your using named exports/import from ES6.
The issue is trying to use state, I believe. Is there any way you can merge the three components using the password validation into one? Or remove the state reference in the helper function and just pass the password as a argument? That should work just fine.
Best way to implement this would be creating a separate global component which does this functionality.
Suppose in components.js , you have :
export const doSomethingElse = () => {
return 1;
}
And wherever you want it you can do by ,
In Cat.js :
import {doSomethingElse} from 'component.js';
doSomethingElse();
Even you can make like a view component like :
export const displayTime = (time) => (
<View>
<Text>{time}</Text>
</View>
)
And you can import in Dog.js like :
import {displayTime} from 'component.js';
render(){
return(
<View>
{this.displayTime('12:00PM');}
</View>
)
}
Hope it helps. feel free for doubts
In fact :
- any prop is possibly a function render(), it's not only the prop render : https://en.reactjs.org/docs/render-props.html
It’s important to remember that just because the pattern is called “render props” you don’t have to use a prop named render to use this pattern. In fact, any prop that is a function that a component uses to know what to render is technically a “render prop”.
- I explain you how work in the design pattern render prop
{this.props.render(this.state)} // It will execute the function (mouse) => Cat mouse={mouse}/> and will instance the component Cat/> with props which are the states of the component Mouse/>
For example, if you want to pass the function doSomethingElse() to the child component , you could do :
class Mouse extends React.Component { doSomethingElse(){ return 1; } render() { return ( <div style={{ height: '100%' }} onMouseMove={this.handleMouseMove}> {this.props.render(this.state, this.doSomethingElse)} </div> ); } } class MouseTracker extends React.Component { render() { return ( <div> <h1>Move the mouse around!</h1> <Mouse render={(mouse, doSomethingElse, ...props) => ( <Cat mouse={mouse} doSomethingElse={doSomethingElse} {...props} /> // Possibly others props if you want )}/> </div> );
java - How to reuse any class or function in react js - Stack Overflow
what is the strategy for reusing small helper functions
reactjs - How to create a reusable function in React - Stack Overflow
reactjs - How to reuse the same functionality in useEffect and another action inside component? - Stack Overflow
Videos
Hi,
I have small functions which I would like to use it across multiple components, where you guys put these kind of stuff? it's probably "utils" or "helpers" folder but do each function has a separate file or what is the general strategy to store/reuse them ?
To reuse the functionality of useEffect and other functions, here you may use custom hook and cover the common functionality in the custom hook and re-use in component where you need.
ex.
import React, { useCallback, useEffect, useState } from "react";
// ---------------------------------- Custom Hook -----------------------------
const useCustomFetch = ({someProp}) => {
const [itemData, setItemData] = useState(null);
const resolveSessionData = useCallback(() => {
const data = database.getItemData(); // fetching data
setItemData(data); // setting fetched data to state
}, []);
useEffect(() => {
if (someProp) {
resolveSessionData(); // or may be fetch data based on props
}
}, [someProp]);
const addNewItem = useCallback(function (dataToAdd) {
/**
* write code to add new item to state
*/
}, [])
const removeExistingItem = useCallback(function (dataOrIndexToRemove) {
/**
* write code to remove existing item from state
*/
}, [])
return {
itemData,
addNewItem,
removeExistingItem,
}
}
// ---------------------------------- Component managing users -----------------------------
const ComponentUser = ({someProp}) => {
const {
addNewItem,
itemData,
removeExistingItem
} = useCustomFetch('users')
const handleAction = useCallback(function (action, data) {
if (action === 'add') {
addNewItem(data) // ex. adding user
} else if (action === 'remove') {
removeExistingItem(data) // ex. removing user
}
}, [])
return <div>
{itemData.map(function () {
/**
* render items here // ex. listing users
*/
})}
<button onClick={handleAction}>
Add / Remove
</button>
</div>;
};
// ---------------------------------- Component managing posts -----------------------------
const ComponentPosts = ({someProp}) => {
const {
addNewItem,
itemData,
removeExistingItem
} = useCustomFetch('posts') // re-using custom hook
const handleAction = useCallback(function (action, data) {
if (action === 'add') {
addNewItem(data) // ex. add new post
} else if (action === 'remove') {
removeExistingItem(data) // ex. remove existing post
}
}, [])
return <div>
{itemData.map(function () {
/**
* render items here // ex. render posts
*/
})}
<button onClick={handleAction}>
Activate Lasers
</button>
</div>;
};
Yes, it is correct way. There is no better way in React.