Asked  7 Months ago    Answers:  5   Viewed   25 times

So I started converting my application from ES2015 to ES6 which uses React.

I have a parent class and a child class like so,

export default class Parent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            code: ''
        };
    }

    setCodeChange(newCode) {
        this.setState({code: newCode});
    }


    login() {
        if (this.state.code == "") {
            // Some functionality
        }
    }

    render() {
        return (
            <div>
                <Child onCodeChange={this.setCodeChange} onLogin={this.login} />
            </div>
        );
    }
}

Child class,

export default class Child extends Component {
    constructor(props) {
        super(props);
    }

    handleCodeChange(e) {
        this.props.onCodeChange(e.target.value);
    }

    login() {
        this.props.onLogin();
    }

    render() {
        return (
            <div>
                <input name="code" onChange={this.handleCodeChange.bind(this)}/>
            </div>
            <button id="login" onClick={this.login.bind(this)}>
        );
    }
}

Child.propTypes = {
    onCodeChange: React.PropTypes.func,
    onLogin: React.PropTypes.func
};

However this causes the following error,

this.state is undefined

It refers to,

if (this.state.code == "") {
    // Some functionality
}

Any idea what could be causing this ?

 Answers

93

You can use arrow function to bind you functions. You need to bind you functions both in child as well as parent components.

Parent:

export default class Parent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            code: ''
        };
    }

    setCodeChange = (newCode) => {
        this.setState({code: newCode});
    }


    login = () => {
        if (this.state.code == "") {
            // Some functionality
        }
    }

    render() {
        return (
            <div>
                <Child onCodeChange={this.setCodeChange} onLogin={this.login} />
            </div>
        );
    }
}

Child

export default class Child extends Component {
    constructor(props) {
        super(props);
    }

    handleCodeChange = (e) => {
        this.props.onCodeChange(e.target.value);
    }

    login = () => {
        this.props.onLogin();
    }

    render() {
        return (
            <div>
                <input name="code" onChange={this.handleCodeChange}/>
            </div>
            <button id="login" onClick={this.login}>
        );
    }
}

Child.propTypes = {
    onCodeChange: React.PropTypes.func,
    onLogin: React.PropTypes.func
};

There are other ways to bind the functions as well such as the one you are using but you need to do that for parent component too as <Child onCodeChange={this.setCodeChange.bind(this)} onLogin={this.login.bind(this)} />

or you can specify binding in the constructor as

Parent:

constructor(props) {
    super(props);
    this.state = {
        code: ''
    };
 this.setCodeChange = this.setCodeChange.bind(this);
 this.login = this.login.bind(this);
}

Child

constructor(props) {
    super(props);
    this.handleCodeChange = this.handleCodeChange.bind(this);
    this.login = this.login.bind(this);
}
Tuesday, June 1, 2021
 
Juicy
answered 7 Months ago
17

Seems like one of your values, with a property key of 'value' is undefined. Test that i1, i2and __i are defined before executing the if statements:

var i1 = document.getElementById('i1');
var i2 = document.getElementById('i2');
var __i = {'user' : document.getElementsByName("username")[0], 'pass' : document.getElementsByName("password")[0] };
if(i1 && i2 && __i.user && __i.pass)
{
    if(  __i.user.value.length >= 1 ) { i1.value = ''; } else { i1.value = 'Acc'; }

    if(  __i.pass.value.length >= 1 ) { i2.value = ''; } else { i2.value = 'Pwd'; }
}
Wednesday, June 2, 2021
 
smiggle
answered 6 Months ago
83

Because you are not returning anything from renderKeywords method, you are returning from map body only. If you don't return anything from function then by default it will return undefined, you need to return the result of map (array of elements).

Like this:

renderKeywords() {
    return this.state.question.map((item, key) => {   //here
        return (
            <span key={key}> {item} </span>
        );
    }); 
}

In short you can write it like this:

renderKeywords() {
   return this.state.question.map((item, key) => <span key={key}> {item} </span> ); 
}

Suggestion:

Assign unique key to each element.

Check this answer for more details about key: Understanding unique keys for array children in React.js

Wednesday, June 9, 2021
 
Arman
answered 6 Months ago
34

Changes:

1. You forgot to bind the onChange method, either use this:

onChange={this.handleCheck.bind(this)}

or define the binding in the constructor:

this.handleCheck = this.handleCheck.bind(this)

2. You used setState in a wrong way, setState is a method you need to call it.

Instead of: this.setState = ({})

it should be: this.setState({})

Thursday, August 26, 2021
 
Alfred
answered 3 Months ago
56

Is the "index.js" module resolution (specifying the containing folder) supported by the ES6 (ECMAScript 2015) modules official standard?

No. ES2015 doesn't contain anything about the module loader or how to interpret module identifiers.


Or is it just "custom" Node.js/CommonJS transpiling behaviour?

Yes. You can read about the module resolution algorithm in the documentation. The relevant part:

require(X) from module at path Y
1. If X is a core module,
   a. return the core module
   b. STOP
2. If X begins with './' or '/' or '../'
   a. LOAD_AS_FILE(Y + X)
   b. LOAD_AS_DIRECTORY(Y + X)
3. LOAD_NODE_MODULES(X, dirname(Y))
4. THROW "not found"
[...]
LOAD_AS_DIRECTORY(X)
1. If X/package.json is a file,
   a. Parse X/package.json, and look for "main" field.
   b. let M = X + (json main field)
   c. LOAD_AS_FILE(M)
2. If X/index.js is a file, load X/index.js as JavaScript text.  STOP
3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP
4. If X/index.node is a file, load X/index.node as binary addon.  STOP

Will it be possible to omit the /index|/index.js part of the import in all browsers as well (when modules will be supported on all browsers)?

Hopefully browser implementations will aim for maximum compatibility with existing module loaders, but for now we don't know. Maybe it doesn't have anything to do with the browser either, but with how the server resolves module identifiers. I confess that I haven't followed the development lately, so any other insights are much appreciated :)

Saturday, September 25, 2021
 
nlucaroni
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share