Woody Wu
Woody Wu

Reputation: 348

Strange class members

I get confused by the 'state' and 'login' members of a class definition from a running example as below:

class Login extends React.Component {
    state = {
        redirectToReferrer: false
    };

    login = () => {
        fakeAuth.authenticate(() => {
            this.setState({ redirectToReferrer: true });
        });
    };

    render() {
        const { from } = this.props.location.state
            || { from: { pathname: "/" } };
        const { redirectToReferrer } = this.state;

        if (redirectToReferrer) {
            return <Redirect to={from} />;
        }

        return (
            <div>
                <p>You must log in to view the page at {from.pathname}</p>
                <button onClick={this.login}>Log in</button>
            </div>
        );
    }
}

For the 'login', I wan to get confirmation that this is a function member of the Login class, right? I can understand the motivation of using an arrow function is a matter of binding of 'this', but I did not see this syntax appeared in my ES6 book. It looks like in the top level of {}, it just defined a variable which is assigned with an arrow function.

For the 'state', this looks like a simple assignment, but I know it must be defining a member of the 'Login' since there is a 'this.state' reference. But I don't understand the syntax, my ES6 book says any instance property must be defined in constructor of the class. Is there any other special meaning of this kind of definition?

Upvotes: 0

Views: 66

Answers (1)

Damian Peralta
Damian Peralta

Reputation: 1876

The standard way of defining initial state in React is like this:

class Login extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            redirectToReferrer: false
        };
    }

    ....

}

But, there are some libraries like unstated, that allow you to define state like this:

// BookContainer.js
import { Container } from 'unstated'
class BookContainer extends Container {
  state = {
    books: [],
    booksVisible: false
  }
  addBook = book => {
    const books = [...this.state.books, book]
    this.setState({ books })
  }
  toggleVisibility = () => {
    this.setState({
      booksVisible: !this.state.booksVisible
    })
  }
}
export {
  BookContainer
}

EDIT: Regarding to the login method, as you already told, is about binding the this

This:

login = () => {
        fakeAuth.authenticate(() => {
            this.setState({ redirectToReferrer: true });
        });
    };

Is the same as doing this:

class Login extends React.Component {
    constructor(props){
        super(props);
        this.state = {
            redirectToReferrer: false
        };
        this.login = this.login.bind(this); // Bind the this
    }

    login(){
        fakeAuth.authenticate(() => {
            this.setState({ redirectToReferrer: true }); // This is not undefined
        });
    }

}

You can find more info in the official unstated page

Upvotes: 1

Related Questions