0

I'm starting to learn react.js, and I've face a situation that I can't get an answer.

This is my components structure(this is just to show hierarchy):

-- ItemContainer
----- ItemList
-------- ItemSingle
----- ItemForm

Where ItemList and ItemForm are siblings, chilren of ItemContainer. And ItemSingle is a child from ItemList.

On each ItemSingle I have a "edit" button, that should update the form with its content, but I'm not able to send from ItemSingle to ItemForm.refs.

This is what I've tried

ItemSingle Component:

var ItemSingle = React.createClass({
    insertEdit: function(edit_item, e){
        e.preventDefault();
        React.findDOMNode(ItemForm.refs.title).value = edit_item.title;
        React.findDOMNode(ItemForm.refs.content).value = edit_item.content;
    },
    render: function() {
        return (
            <div className="box">
                <div className="box-body bigger-box">
                    <h4>
                        <strong>#{this.props.index + 1}</strong>
                        <span className="title">{this.props.title}</span>
                        <span className="float-right box-option">
                            <a href="#" onClick={this.insertEdit.bind(this, this.props)}>Edit</a>
                        </span>
                    </h4>
                    <div className="text" dangerouslySetInnerHTML={{__html: this.props.content}} />
                </div>
            </div>
        );
    }
});

ItemForm Component:

var ItemForm = React.createClass({
    handleSubmit: function(e) {
        e.preventDefault();
        var title = React.findDOMNode(this.refs.title).value.trim();
        var content = React.findDOMNode(this.refs.content).value.trim();

        if(!title || !content){ return false;   }

        this.props.onItemsAdd({title: title, content: content});
        React.findDOMNode(this.refs.title).value = '';
        React.findDOMNode(this.refs.content).value = '';
        $('textarea').trumbowyg('empty');
        return true;
    },
    componentDidMount: function() {
        $('textarea').trumbowyg();
    },
    render: function() {
        return (
            <div className="form-container">
                <form className="form" method="POST">
                    <div className="form-group">
                        <input type="text" className="form-control" ref="title"/>
                    </div>
                    <div className="form-group">
                        <textarea ref="content"></textarea>
                    </div>
                    <div className="form-group">
                        <a className="btn btn-success btn-flat btn-block btn-lg" onClick={this.handleSubmit}><i className="fa fa-save"></i>&nbsp;&nbsp;&nbsp;Save</a>
                    </div>
                </form>
            </div>
        );
    }
});

And this is the error I got on ItemSingle line number 4:

Uncaught TypeError: Cannot read property 'title' of undefined
rafaelmorais
  • 1,323
  • 2
  • 24
  • 49

1 Answers1

2

Refs in React are not meant to be used like this.

If you have not programmed several apps with React, your first inclination is usually going to be to try to use refs to "make things happen" in your app. If this is the case, take a moment and think more critically about where state should be owned in the component hierarchy. Often, it becomes clear that the proper place to "own" that state is at a higher level in the hierarchy. Placing the state there often eliminates any desire to use refs to "make things happen" – instead, the data flow will usually accomplish your goal.

In your app you will need state, probably in ItemList component, and methods to change this state should be passed to the ItemSingle components.

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

arturkin
  • 958
  • 1
  • 6
  • 19
  • What is this "state" thing you mention, I'm having some difficulties understanding the concept. Thanks for your answer. (btw, nice rise against logo) – rafaelmorais Sep 16 '15 at 17:59
  • 1
    React is using one-way data flow concept where `props` is the immutable data that all components use, and `state` is representation of data that user creates in your app. Understanding `state` and `props` is crucial in learning React. Please follow the tutorial, https://facebook.github.io/react/docs/tutorial.html it helped me to understand some of the React basics. – arturkin Sep 16 '15 at 18:11
  • 1
    Thats where I started, I've learned some basic, guess that wasn't enought to get the concept. Thanks for your help, I'll spend more time reading and trying to achieve this. – rafaelmorais Sep 16 '15 at 19:09