Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to share functions between components in React

Tags:

reactjs

People also ask

How do you pass a function from one component to another in React?

For passing the data from the child component to the parent component, we have to create a callback function in the parent component and then pass the callback function to the child component as a prop. This callback function will retrieve the data from the child component.

How many ways we can communicate between components in React?

I saw that the question is already answered, but if you'd like to learn more details, there are a total of 3 cases of communication between components: Case 1: Parent to Child communication. Case 2: Child to Parent communication. Case 3: Not-related components (any component to any component) communication.


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/file'

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;

If you want to manipulate state in helper functions follow this:

  1. Create a Helpers.js file:

    export function myFunc(){ return this.state.name; //define it according to your needs }

  2. Import helper function in your component file:

    import {myFunc} from 'path-to/Helpers.js'

  3. In your constructor add that helper function to the class

    constructor(){ this.myFunc = myFunc.bind(this) }

  4. In your render function use it:

    render(){ <div>{this.myFunc()}</div> }


Here are some examples on how you can reuse a function (FetchUtil.handleError) in a React component (App).

Solution 1: Using CommonJS module syntax

module.exports = {
  handleError: function(response) {
    if (!response.ok) throw new Error(response.statusText);
    return response;
  },
};

Solution 2: Using "createClass" (React v16)

util/FetchUtil.js

const createReactClass = require('create-react-class');

const FetchUtil = createReactClass({
  statics: {
    handleError: function(response) {
      if (!response.ok) throw new Error(response.statusText);
      return response;
    },
  },
  render() {
  },
});

export default FetchUtil;

Note: If you are using React v15.4 (or below) you need to import createClass as follows:

import React from 'react';
const FetchUtil = React.createClass({});

Source: https://reactjs.org/blog/2017/04/07/react-v15.5.0.html#migrating-from-reactcreateclass

Component (which reuses FetchUtil)

components/App.jsx

import Categories from './Categories.jsx';
import FetchUtil from '../utils/FetchUtil';
import Grid from 'material-ui/Grid';
import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {categories: []};
  }

  componentWillMount() {
    window
      .fetch('/rest/service/v1/categories')
      .then(FetchUtil.handleError)
      .then(response => response.json())
      .then(categories => this.setState({...this.state, categories}));
  }

  render() {
    return (
      <Grid container={true} spacing={16}>
        <Grid item={true} xs={12}>
          <Categories categories={this.state.categories} />
        </Grid>
      </Grid>
    );
  }
}

export default App;

Another solid option other than creating a util file would be to use a higher order component to create a withComponentMapper() wrapper. This component would take in a component as a parameter and return it back with the componentMapper() function passed down as a prop.

This is considered a good practice in React. You can find out how to do so in detail here.