7

I've been building React components for my latest app. I know I can reuse components which has helped keep my code DRY.

I wanted to know if I could reuse functions. I know there has to be a way.

Right now I have three components using a password validation function.

passwordValidation() {
  const length = this.state.password.length;
  if (length > 7) return 'success';
  else if (length > 4) return 'warning';
  else if (length > 0) return 'error';
}

I created a helper file - helpers.jsx and added:

export function passwordValidation() {
  const length = this.state.password.length;
  if (length > 7) return 'success';
  else if (length > 4) return 'warning';
  else if (length > 0) return 'error';
}

I then imported it into my component

import { passwordValidation } from '../helpers.jsx'

I keep getting the error "passwordValidation is not a function" when I try binding "this" in my constructor.

If I invoke it in the input tag, I am getting "cannot read property state of undefined."

Just trying to see where I am going wrong. Everything works if I define it in my class and add this.passwordValidation = this.passwordValidation.bind(this).

I'll go back to what I was doing if this isn't best practice, but I'm under the assumption that I should be able to import functions to make life easier and my code cleaner!

1
  • Can you add the part where you tried to bind but got an error please? Commented Oct 19, 2017 at 21:13

3 Answers 3

17

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));
Sign up to request clarification or add additional context in comments.

1 Comment

This worked. Dumb mistake on my part copying the method directly to a helper with "this.state.password.length" and not making it universal.
3

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.

1 Comment

That wound up being the issue!
2
import { passwordValidation } from '../helpers.jsx'

essentially says:

var { passwordValidation } = (function passwordValidation () {...});

passwordValidation is a function, and functions are objects in JS, so it's essentially looking for:

var passwordValidation = (function...(){...}).passwordValidation;

Instead, just assign the function directly to passwordValidation:

import passwordValidation from '../helpers.jsx'

or call require directly if you're in a context where require is available.

const passwordValidation = require('...resource...')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.