Zen
Zen

Reputation: 5500

Can I modify state directly when using React with MobX?

The only reason why I should not do it is to let react update view. https://facebook.github.io/react/docs/state-and-lifecycle.html#using-state-correctly
But It seems that MobX-react do these dirty work for me. I just need to mark this.state as observable, and everything works as expected. Are there any drawbacks? I don't want to throw all states into a giant store.

JSFiddle link

Code:

const {observable, computed} = mobx;
const {observer} = mobxReact;
const {Component} = React;

@observer
class Form extends React.Component{
    @observable state = {
        username: '',
        password: '',
    };

    constructor(...args) {
        super(...args);
        this.handleSubmit = this.handleSubmit.bind(this)
    }

    render() {
        return  <form onSubmit={this.handleSubmit}>
                    <label>
                    Name:
                    <input type="text" value={this.state.username} onChange={event => this.state.username = event.target.value} />
                    </label>
                    <div>username: {this.state.username}</div>
                    <input type="submit" value="Submit" />
                </form>;
    }

    handleSubmit(event: Event) {
        event.preventDefault();
        console.log(this.state.username);
    }
}

ReactDOM.render(
    <div>
        <Form />
        <mobxDevtools.default />
    </div>
, document.getElementById('mount'));

Upvotes: 1

Views: 1698

Answers (2)

Tholle
Tholle

Reputation: 112807

It's best to bypass state altogether and just put the observable data directly on the class.

Example (JS Bin)

const {observable, computed} = mobx;
const {observer} = mobxReact;
const {Component} = React;

@observer
class Form extends React.Component{
    @observable username = '';
    @observable password = '';

    constructor(props) {
        super(props);
        this.handleSubmit = this.handleSubmit.bind(this)
    }

    render() {
        return <form onSubmit={this.handleSubmit}>
            <label>
                Name:
                <input type="text" value={this.username} onChange={event => this.username = event.target.value} />
            </label>
            <div>username: {this.username}</div>
            <input type="submit" value="Submit" />
        </form>;
    }

    handleSubmit(event: Event) {
        event.preventDefault();
        console.log(this.username, this.password);
    }
}

ReactDOM.render(
    <div>
        <Form />
    </div>
, document.getElementById('mount'));

Upvotes: 4

Jesvin Jose
Jesvin Jose

Reputation: 23098

You can name it form instead of state and it won't care, its bypassing React's setState and rerender mechanism. React setState, in addition to merging state updates to the component, also tells your component to rerender. React components have a forceUpdate.

MobX also does both, by updating observables you also send a message to connected observer components to update themselves. And having a central state store is an established pattern with React.

Upvotes: 2

Related Questions