VB_
VB_

Reputation: 45692

PureRenderMixin & state management design

I have some top-level component (RegisrationPage) with state, which pass it state/props to dump bottom-level components (InputField, Dropdown, Datepicker). Bottom-level components change RegistrationPage's state with help of callbacks.

Problem: PureRenderMixin doesn't work since I have to bind state-change-callback that are passed to bottom-level components.

Question: how to make PureRenderMixin works in the most elegant way?

Let's explain it with code:

InputBlock:

const React = require('react'),
      PureRenderMixin = require('react-addons-pure-render-mixin');

module.exports =  React.createClass({
    mixins: [PureRenderMixin],

    propTypes: {
        input: React.PropTypes.string,
        onChange: React.PropTypes.func
    },

    render() {
        //PROBLEM - is re-rendered each time , since onChange callback each time is an different object due bind method call
    }

});

RegistrationPage:

RegistrationPage = React.createClass({  

    /**
     * Since all state is held by `RegistrationPage` and bottom-level components are dump,
     * I do _onFieldChange.bind - _onFieldChange should know which field should be changed
     */
    render() {
        return CreateFragment({
            email: <InputBlock
                input={this.state.email}
                onChange={this._onFieldChange.bind(self, 'email')}/>,
            firstName: <InputBlock
                input={this.state.firstName}
                onChange={this._onFieldChange.bind(self, 'firstName')}/>,
            .........
        });
    },

    _onFieldChange(key, event) {
        //Save registered progress to store and re-render the component
        AppActionCreators.saveRegisterProgress(this.state);
    }
})

My workaround: just pass inputFieldName as extra property and do binding inside bottom-level component.

Upvotes: 4

Views: 126

Answers (1)

wuct
wuct

Reputation: 10477

The problem is .bind() returns a new function every time you invokes it. To avoid it, you should create functions outside rendering. For example:

    RegistrationPage = React.createClass({  
        render() {
            return CreateFragment({
                email: <InputBlock
                    input={this.state.email}
                    onChange={this._onEmailChange}/>,
                firstName: <InputBlock
                    input={this.state.firstName}
                    onChange={this._onFirstNameChange}/>,
                .........
            });
        },

        _onFieldChange(key, event) {
            //Save registered progress to store and re-render the component
            AppActionCreators.saveRegisterProgress(this.state);
        }

        _onEmailChange() {
            this._onFieldChange('email')
        }

        _onFirstNameChange() {
            this._onFieldChange('firstName')
        }
    })

Upvotes: 1

Related Questions