loading...

Usestate hook not working inside arrow component.

itssimondev profile image Simone Aronica Updated on ・3 min read

The story

So I'm trying to replicate a Material Design text field, and I think I've managed to do that pretty well, as in this Code Sandbox: https://1d053.csb.app/

Now the only difference between this sandbox and the component I'll show later on is the use of scss modules instead of pure scss.

The problem

When I test this component it results in an Invalid Hook Call.
This is the error:

main.js:170 Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.
    at resolveDispatcher (react.development.js:1590)
    at useState (react.development.js:1618)
    at MDTextField (index.js:25)
    at hi (main.js:170)
    at Rs (main.js:170)
    at Ol (main.js:170)
    at Pl (main.js:170)
    at wl (main.js:170)
    at yl (main.js:170)
    at ou (main.js:170)

Now to my knowledge I see no reason for it to result in an invalid hook call.

The code

textfield/index.js

const MDTextField = props => {
    const [isFocused, setFocused] = useState(false);
    const [isEmpty, setEmpty] = useState(true);
    const _setFocus = () => {
        setFocused(true);
    };
    const _setUnfocus = () => {
        setFocused(false);
    };
    const _handleChange = e => {
        setEmpty(e.target.value.length > 0 ? false : true);
    };
    return (
        <div
        style={{
            borderColor: props.error
            ? "rgb(176, 0, 32)"
            : props.color && isFocused
            ? props.color
            : ""
        }}
        className={`${props.outlined ? style.MDTextFieldOutlined : style.MDTextField} ${palette.MDTextField} ${props.className ? props.className : ''}`}
        onFocus={_setFocus}
        onBlur={_setUnfocus}
        >
        <span
            className={`${style.Label} ${palette.Label}`}
            style={{
            color: props.error
                ? "rgb(176, 0, 32)"
                : props.color && isFocused
                ? props.color
                : "",
            transform: isEmpty
                ? ""
                : `translateY(-${props.outlined ? "50" : "50"}%) scale(.75)`
            }}
        >
            {props.label + (props.error ? "*" : "")}
        </span>
        <span className={style.InputWrapper}>
            <input
            style={{
                caretColor: props.error
                ? "rgb(176, 0, 32)"
                : props.color
                ? props.color
                : ""
            }}
            className={`${style.TextInput} ${palette.TextInput}`}
            onChange={_handleChange}
            />
        </span>
        </div>
    );
};

Also

Thank you for taking the time to read this issue, and I hope to find someone able enough to understand this error.

Edits:

This is the code I use to call the component:

const App = () => {
    const style = useStyles();
    return <>
        <div className={style.bg}>
            <MDCard media='https://images7.alphacoders.com/909/909467.jpg' >
                <MDCardTitle>Title goes here</MDCardTitle>
                <MDCardSubtitle>Secondary text</MDCardSubtitle>
                <MDCardSection>Greyhound divisively hello coldly wonderfully marginally far upon excluding.</MDCardSection>
                <MDCardSection>Tags: <b>#reactjs</b></MDCardSection>
                <MDDivider />
                <MDButton text>button</MDButton>
                <MDButton text>button</MDButton>
            </MDCard>
            <MDCard media='https://images7.alphacoders.com/909/909467.jpg' dark>
                <MDCardTitle>Title goes here</MDCardTitle>
                <MDCardSubtitle>Secondary text</MDCardSubtitle>
                <MDCardSection>Greyhound divisively hello coldly wonderfully marginally far upon excluding.</MDCardSection>
            </MDCard>
            <MDCard>
                <MDCardTitle>Title goes here</MDCardTitle>
                <MDCardSubtitle>Secondary text</MDCardSubtitle>
                <MDButton text>Button</MDButton>
            </MDCard>
            <MDCard dark>
                <MDCardTitle>Title goes here</MDCardTitle>
                <MDCardSubtitle>Secondary text</MDCardSubtitle>
                <MDButton accentColor='#1da3dc' text>button</MDButton>
            </MDCard>
            <div className={style.bw}>
                <MDButton>Button</MDButton>
                <MDButton outlined>Button</MDButton>
                <MDButton text>Button</MDButton>
            </div>
            <div className={style.bw}>
                <MDButton accentColor='#212121'>Button</MDButton>
                <MDButton outlined accentColor='#212121'>Button</MDButton>
                <MDButton text accentColor='#212121'>Button</MDButton>
            </div>
            <div className={style.br}>
                <MDFloatingButton >+</MDFloatingButton>
                <MDFloatingButton mini>+</MDFloatingButton>
            </div>
            <div className={style.bw}>
                <MDTextField />
            </div>
        </div>
    </>
}

Every other component is fine since if I remove this component, everything else works.

Posted on by:

itssimondev profile

Simone Aronica

@itssimondev

Hi, my name is Simone and I'm a CS student in Italy at the last year of High School.

Discussion

pic
Editor guide
 

Post link to full example. Code of the component is ok codesandbox.io/s/goofy-feynman-vl3ny

Do you try to call component as function instead of using as component?

 

I've edited the post.

 

Post link to codesandbox (not preview but sandbox itslef) where we can see error.

I solved it. Apparently all I had to do was setting react as an external.

hi simon could you tell me how you solved it? I have the same problem :(

 

Are you importing React this way:

import React, { useState } from 'react' (correct),

rather than:

import React, { useState } from 'React' (incorrect)?

 

I am, my bad, I didn't specify: the issue is not when compiling, the issue is when running the code on a page.