1

I'm following a tutorial and I am getting confused with my arrow version of it and their function version. I have a LoaderButton.js and I can write the component as a normal functional component or an arrow component:

Functional Component:

export default function LoaderButton({
  isLoading,
  className = "",
  disabled = false,
  ...props
}) {
  return (
    <Button
      className={`LoaderButton ${className}`}
      disabled={disabled || isLoading}
      {...props}
    >
      {isLoading && <Glyphicon glyph="refresh" className="spinning" />}
      {props.children}
    </Button>
  );
}

Arrow Component:

const LoaderButton = (
  isLoading,
  className = "",
  disabled = false,
  ...props ) => (
    <Button
      className={`LoaderButton ${className}`}
      disabled={disabled || isLoading}
      {...props}
    >
      {isLoading && <Glyphicon glyph="refresh" className="spinning" />}
      {props.children}
    </Button>
  )


export default LoaderButton

And the LoaderButton is imported and used here in my Login.js:

export default function Login() {
  const history = useHistory();
  const { userHasAuthenticated } = useAppContext();
  const [isLoading, setIsLoading] = useState(false);
  const [fields, handleFieldChange] = useFormFields({
    email: "",
    password: ""
  });

  function validateForm() {
    return fields.email.length > 0 && fields.password.length > 0;
  }

  async function handleSubmit(event) {
    event.preventDefault();

    setIsLoading(true);

    try {
      await Auth.signIn(fields.email, fields.password);
      userHasAuthenticated(true);
      history.push("/");
    } catch (e) {
      onError(e);
      setIsLoading(false);
    }
  }

  return (
    <div className="Login">
      <form onSubmit={handleSubmit}>
        <FormGroup controlId="email" bsSize="large">
          <ControlLabel>Email</ControlLabel>
          <FormControl
            autoFocus
            type="email"
            value={fields.email}
            onChange={handleFieldChange}
          />
        </FormGroup>
        <FormGroup controlId="password" bsSize="large">
          <ControlLabel>Password</ControlLabel>
          <FormControl
            type="password"
            value={fields.password}
            onChange={handleFieldChange}
          />
        </FormGroup>
        <LoaderButton
          block
          type="submit"
          bsSize="large"
          isLoading={isLoading}
          disabled={!validateForm()}
        >
          Login
        </LoaderButton>
      </form>
    </div>
  );
}

The standard functional component works as expected.

But the arrow function component seems to have isLoading stuck to true AND gets this error:

Warning: Failed prop type: Invalid prop `disabled` of type `object` supplied to `Button`, expected `boolean`.

I thought arrow function components were supposed to be a simpler way to write function components.

I keep thinking it has to do with binding and therefore it's somehow binding the props I have different but I can't find any information on the differences of their bindings. I thought if my Login.js is binding according to the way it's written then I should be fine?

I honestly would prefer to write using an arrow function syntax.

1 Answer 1

1

They aren't quite equivalent. You didn't destructure props correctly. Wrap all the props with {} so your functional component is taking a single props argument.

const LoaderButton = ({
  isLoading,
  className = "",
  disabled = false,
  ...props
}) => (
  <Button
    className={`LoaderButton ${className}`}
    disabled={disabled || isLoading}
    {...props}
  >
    {isLoading && <Glyphicon glyph="refresh" className="spinning" />}
    {props.children}
  </Button>
);

export default LoaderButton
Sign up to request clarification or add additional context in comments.

2 Comments

Ah, wow duh! So was it reading disabled = false, ...props ?
@KyleCalica-St No, isLoading is the first argument. React would read that as "props" and ignore the rest.

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.