React:避免Refs访问子组件的状态

时间:2016-01-14 17:22:04

标签: reactjs state

所以我读过在访问子组件时我们应该尝试避免引用

React refs with components

https://facebook.github.io/react/docs/more-about-refs.html

然而,就我而言,在我的情况下,我想不出办法避免这种情况。


情境:

我有一个 MyForm 父组件,其中包含 TagInput 子组件,类似于Stackoveflow的“标签”输入字段。当用户键入输入+ SPACE时,标记将添加到 TagInput 的内部状态。当用户提交表单时,所选标签列表将发布到我的服务器。


实现:

var MyForm = React.createClass({
    submit: function() {
        var selectedTags = this.refs.tagInput.state.selectedTags;

        $.post(
            SERVER_URL,
            data: { tags: selectedTags }
        );
    },

    render: function() {
        return (
            <form onSubmit={this.submit}>
                <TagInput ref="tagInput">
            </form>
        );
    }
});


var TagInput = React.createClass({
    getInitialState: function() {
        return {
            selectedTags: []
        }
    },

    // This is called when the user types SPACE in input field
    handleAddTag: function(tag) {
        this.setState({
            selectedTags: this.state.selectedTags.concat(tag);
        });
    },

    render: function() {
        return (
            <form>
                <ul>{this.state.selectedTags}</ul>
                <input type="text" />
            </form>
        );
    }
});


上面的代码工作正常,并做了预期的事情。唯一的问题是我使用refs直接访问Child组件的内部状态,我不确定这是否是正确的“React”方式。

我想一个选项是在 MyForm 而不是 TagInput 中维持“selectedTags”状态。这在我的案例中没有意义,因为实际上我的表单包含5个 TagInput 组件和许多其他要管理的状态..

有人能想出改善设计的方法吗?或者在我的情况下使用refs是不可避免的?

由于

1 个答案:

答案 0 :(得分:2)

您可以将handleAddTag从父组件传递到子组件中,并将所选标签的状态保留在表单组件中。现在,当您提交表单时,您将从表单上的状态中提取而不是使用引用。

Template.List.events({
    'change #categories':function(evt){

         Meteor.subscribe("videos-pub-sub", $(evt.target).val(), function(){
               //to empty the table
               $('#video_table').find('tbody').empty();
               var vids = Videos.find({}).fetch();
               Session.set("videos-session", Videos.find({}).fetch());
         });

     }
});

我发现使用refs来获取一些数据并不像使用refs来修改UI一样糟糕,因为它会导致UI不与你的州或你的应用程序内联。