Search code examples
reactjsbabeljsbabel-loader

How correctly separate a function in a component?


I need to move the function call from the component to a separate function

<MyComponent 
    getLabel={ ({buttonLabel, value }) => {
        console.log('Placeholder');
        console.log(buttonLabel);
        console.log(value ? value.map( c => { return c.label}) : []);
        return 'test;
    }} />

I tried to separate it like this:

class Results extends Component {
    constructor(props) {
        super(props);
        this.state = {
        }

        this.getLabel = this.getLabel.bind(this);

        getLabel = (buttonLabel, value) => {
            console.log('Placeholder');
            console.log(buttonLabel);
        }
    }

    //this throws a compile error
    /*getLabel = (buttonLabel, value) => {
        console.log('Placeholder');
        console.log(buttonLabel);
    }*/

render() {
    return (
        <React.Fragment>
<MyComponent 
    getLabel={this.getLabel} />

        </React.Fragment>
    );
}
}

The above example throws error:

Uncaught TypeError: Cannot read property 'bind' of undefined

on rendering in browser.

If I move the function outside of the constructor, it throws a compile error:

Module build failed (from ./node_modules/babel-loader/lib/index.js):

Support for the experimental syntax 'classProperties' isn't currently enabled

What is wrong there?

This is my .babelrc:

{
    "presets": [
        "@babel/preset-env",
        "@babel/preset-react"
    ],
    "plugins": [
        [
          "@babel/plugin-proposal-class-properties"
        ]
    ]
  }

EDIT

I don't know why it wasn't working properly before, might be webpack error or so, not sure.

I have provided below the solution that worked for me which is very close to what I intended initially.


Solution

  • You almost had it in you commented out part. getLabel(buttonLabel, value) { would have been the correct start of defining a method.

    A syntactically correct way of doing this should be the following:

    class Results extends Component {
        constructor(props) {
            super(props);
            this.state = {};
    
            this.getLabel = this.getLabel.bind(this);
        }
    
        getLabel(buttonLabel, value) {
            console.log('Placeholder');
            console.log(buttonLabel);
        }
    
        render() {
            return (
                <React.Fragment>
                    <MyComponent getLabel={this.getLabel}/>
                </React.Fragment>
            );
        }
    }