将React.js状态存储在组件所有者中



我有我的组件所有者:

var React = require('react');
var Backbone = require('backbone');
var GlobalMessage = require('./shared/global-message.jsx');
module.exports = React.createClass({
    getInitialState: function() {
        return {
            global_message: {
                message: 'error',
                type: ''
            }
        };
    },
    componentWillMount: function() {
        Backbone.on('global-message', function(data) {
            this.setState({
                global_message: data
            });
        }.bind(this));
    },
    render: function() {
        return (
            <div>
                <GlobalMessage message={this.state.global_message.message} type={this.state.global_message.type} />
            </div>
        );
    }
});

和我的global-message.jsx

var React = require('react/addons');
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
module.exports = React.createClass({
    render: function() {
        return (
            <div className='global-message-wrap'>
                <ReactCSSTransitionGroup transitionName='global-message'>
                    <p className='global-message-text' key={this.props.message}>{this.props.message}</p>
                </ReactCSSTransitionGroup>
            </div>
        );
    }
});

这一切都可以,当我进行trigger我的Backbone事件时,一切都可以更新。

但是。

如果这是React Way™,那么就这样,但是对我来说,将存储在父母中的组件中的状态感到不自然。对我来说,如果我有一个global-message模块,那么我应该能够初始化它,然后持有自己的数据?

我还能如何处理/整理一下?

除了上面的评论。如果您的全局消息状态仅由您的global-message.jsx组件使用,则可以将所有订阅逻辑移至此组件:

var React = require('react/addons');
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
module.exports = React.createClass({
    getInitialState: function() {
        return {
            message: 'error',
            type: ''
        };
    },
    componentWillMount: function() {
        Backbone.on('global-message', function(data) {
            this.setState(data);
        }.bind(this));
    },        
    render: function() {
        if (!this.state.type) {
            return null;
        }
        return (
            <div className='global-message-wrap'>
                <ReactCSSTransitionGroup transitionName='global-message'>
                    <p className='global-message-text' key={this.state.message}>{this.state.message}</p>
                </ReactCSSTransitionGroup>
            </div>
        );
    }
});

您可以在任何地方使用任何组件:

var React = require('react');
var Backbone = require('backbone');
var GlobalMessage = require('./shared/global-message.jsx');
module.exports = React.createClass({
    render: function() {
        return (
            <GlobalMessage />
        );
    }
});

但是,如果组件的某些孩子之间共享某种状态,则最好将状态存储在其父部件中,例如:

var UserInfoComponent = React.createClass({
    getInitialState: function () {
        return api.getCurrentUser(); // {firstname: 'John', lastname: 'Smith', avatar: 'http://...'}
    },
    componentDidMount: function () {
        // subscribe logic here
    },
    componentWillUnmount: function () {
        // unsubscribe logic here
    }
    render: function () {
        return (
            <div>
                <UserAvatarComponent avatar={this.state.avatar} />
                <UserMenuComponent user={this.state} />
            </div>
        );
    }
});

和使用父母组件的其他变体作为数据提供商:例如,您拥有和ErrorMessageComponent,它封装了一些用于显示一些错误消息的代码。因此,最好通过避免在组件内进行数据提取并为其父母留下此逻辑来保持此组件清洁和重复使用。因此,在不同的情况下,您可以使用一个组件通过使用道具向组件提供信息来显示不同的错误。

最新更新