最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - General structure when using React.js - Stack Overflow

programmeradmin0浏览0评论

Looking at the Virtual DOM in React.js and by doing a few performance tests, I'm very interested in this library. It seems like the perfect add-on to Backbone's awesome model, router and collection structure.

However, due to the lack of quality tutorials and courses out there, I'm left with a few questions I hope someone here will be able to answer:

HTML templates

Does React completely do away with the notion of HTML templates? I'm talking about having your view markup in a separate HTML file (Or on the same page in a <script type=text/template> tag). You know, like you do with underscore.js Handlebars etc ...

The Starter kit examples all seem to have the JSX or React.DOM functions right inside your view classes, which seems a little messy to me, and I can see this getting a little out of hand, as your views grow in complexity.

Here's an example that renders 2 values and the sum of them, using a basic Twitter Bootstrap panel element with a nested table.

var CustomView = React.createClass({
    render: function() {
        var x = this.props.x;
        var y = this.props.y;

        return (
            <div className="panel panel-primary">
                <div className="panel-heading">
                    <h1 className="panel-title">Should I put all this markup somewhere else?</h1>
                </div>
                <div className="panel-body">
                    <table className="table">
                        <thead>
                            <tr>
                                <th>X</th>
                                <th>Y</th>
                                <th>Combined val</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td>{x}</td>
                                <td>{y}</td>
                                <td>{x + y}</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        );
    }
});

I'm not interested in knowing whether it's possible or not to move this stuff to a separate file, rather, I'm trying to understand what's considered the best practise when working with React.

Updating and setting data

The Why React page states the following:

Simply express how your app should look at any given point in time, and React will automatically manage all UI updates when your underlying data changes.

I'm not fully understanding how this works. For instance, take the React component from before <CustomView x="20" y="10">. Initially I would render it like so:

var x = 20;
var y = 10;

React.renderComponent(
    <CustomView x={x} y={y} />,
    document.getElementById('view-container')
);

Now, when I want to update CustomView any time x changes, how should I proceed? React is supposed to be an alternative to the data binding you find in Angular and Ember, without doing a 2-way binding, so how do I make this happen? How do I tell CustomView to keep an eye on x and automatically re-render when it changes?

Naturally, just assigning x a new value does nothing.

I know there's the setState method, but I still manually have to call that, right? So if I was working with a React view and a Backbone model, the code could look something like this:

// Data model: Backbone.js
var model = new Backbone.Model({text: "Please help! :)"});

// Create view class
var View = React.CreateClass({
    render: function() {
        return (
            <p>{this.props.text}</p>
        );
    }
});

// Instantiate new view
var view = React.renderComponent(
    <View text={model.get("text")}>,
    document.getElementById('view-container')
);

// Update view
model.on("change:text", function(model, newValue) {
    view.setState({
        text: newValue
    });
});

// Change data
model.set("text", "I do not understand this ...");

That seems like a really strange setup, and I'm almost sure this can't be the way you're supposed to do it.

I would love some pointers to help me move in the right direction here.

Thank you in advance for any feedback and help.

Looking at the Virtual DOM in React.js and by doing a few performance tests, I'm very interested in this library. It seems like the perfect add-on to Backbone's awesome model, router and collection structure.

However, due to the lack of quality tutorials and courses out there, I'm left with a few questions I hope someone here will be able to answer:

HTML templates

Does React completely do away with the notion of HTML templates? I'm talking about having your view markup in a separate HTML file (Or on the same page in a <script type=text/template> tag). You know, like you do with underscore.js Handlebars etc ...

The Starter kit examples all seem to have the JSX or React.DOM functions right inside your view classes, which seems a little messy to me, and I can see this getting a little out of hand, as your views grow in complexity.

Here's an example that renders 2 values and the sum of them, using a basic Twitter Bootstrap panel element with a nested table.

var CustomView = React.createClass({
    render: function() {
        var x = this.props.x;
        var y = this.props.y;

        return (
            <div className="panel panel-primary">
                <div className="panel-heading">
                    <h1 className="panel-title">Should I put all this markup somewhere else?</h1>
                </div>
                <div className="panel-body">
                    <table className="table">
                        <thead>
                            <tr>
                                <th>X</th>
                                <th>Y</th>
                                <th>Combined val</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                                <td>{x}</td>
                                <td>{y}</td>
                                <td>{x + y}</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        );
    }
});

I'm not interested in knowing whether it's possible or not to move this stuff to a separate file, rather, I'm trying to understand what's considered the best practise when working with React.

Updating and setting data

The Why React page states the following:

Simply express how your app should look at any given point in time, and React will automatically manage all UI updates when your underlying data changes.

I'm not fully understanding how this works. For instance, take the React component from before <CustomView x="20" y="10">. Initially I would render it like so:

var x = 20;
var y = 10;

React.renderComponent(
    <CustomView x={x} y={y} />,
    document.getElementById('view-container')
);

Now, when I want to update CustomView any time x changes, how should I proceed? React is supposed to be an alternative to the data binding you find in Angular and Ember, without doing a 2-way binding, so how do I make this happen? How do I tell CustomView to keep an eye on x and automatically re-render when it changes?

Naturally, just assigning x a new value does nothing.

I know there's the setState method, but I still manually have to call that, right? So if I was working with a React view and a Backbone model, the code could look something like this:

// Data model: Backbone.js
var model = new Backbone.Model({text: "Please help! :)"});

// Create view class
var View = React.CreateClass({
    render: function() {
        return (
            <p>{this.props.text}</p>
        );
    }
});

// Instantiate new view
var view = React.renderComponent(
    <View text={model.get("text")}>,
    document.getElementById('view-container')
);

// Update view
model.on("change:text", function(model, newValue) {
    view.setState({
        text: newValue
    });
});

// Change data
model.set("text", "I do not understand this ...");

That seems like a really strange setup, and I'm almost sure this can't be the way you're supposed to do it.

I would love some pointers to help me move in the right direction here.

Thank you in advance for any feedback and help.

Share Improve this question edited Jun 15, 2014 at 17:10 Ahrengot asked Jun 15, 2014 at 17:04 AhrengotAhrengot 1,5891 gold badge17 silver badges29 bronze badges 1
  • I've not used it myself, but it might be worth taking a look at react-bootstrap. It appears to be the Bootstrap components factored into React components, so instead of using a large chunk of panel html in CustomView, you could use <Panel header="foo bar">... table ...</Panel> instead. – Douglas Commented Jun 15, 2014 at 22:49
Add a comment  | 

3 Answers 3

Reset to default 8

Does React completely do away with the notion of HTML templates?

Yes, in favor of declaring your views with JavaScript. It also allows the Virtual DOM structure to work efficiently.

The Starter kit examples all seem to have the JSX or React.DOM functions right inside your view classes, which seems a little messy to me, and I can see this getting a little out of hand, as your views grow in complexity.

You shouldn't allow your view to grow in complexity. Make big components from small components, and you won't have an issue. If you feel it's getting complex, you can always reorganize it.

I know there's the setState method, but I still manually have to call that, right? So if I was working with a React view and a Backbone model [...]

You should search for "react backbone", and you'll find some blog posts and code examples. They're often used together. Feel free to add any links you found helpful here.

You're on the right path, however there are two things to fix. One is a bug, the other is a preferred pattern.

The bug: In the View, you are using this.props.text (good!), but you are using setState in the model listener. This sets the this.state.text value, which you are not using, so it won't work. setState should 'only' be used from inside the component itself - for all intents and purposes, think of it as a protected method. Instead, there is the setProps function, which is intended to be used only from outside the component.

The preferred pattern: The usage of setProps will soon be deprecated, as it causes a number of subtle issues. The better thing to do is just re-render the whole component each time. The right code in your case is:

// Data model: Backbone.js
var model = new Backbone.Model({text: "Please help! :)"});

// Create view class
var View = React.CreateClass({
    render: function() {
        return (
            <p>{this.props.text}</p>
        );
    }
});

function rerender() {
  React.renderComponent(
    <View text={model.get("text")}>,
    document.getElementById('view-container')
  );
}

// Update view
model.on("change:text", function(model, newValue) {
    rerender();
});

rerender();

Thank you for the replies guys,

So, am I correct in assuming that if I want the views to observe the data models, what I end up with is actually pretty close to Backbone view code, where you hook up event listeners in the intialize method? Here's a quick example that works:

var model = new Backbone.Model({
    text: "Hey there :)"
});

var TextBox = React.createClass({
    getInitialState: function() {
        return this.props.model.toJSON();
    },
    componentWillMount: function() {
        this.props.model.on("change:text", function(model, newText) {
            this.setState({
                text: newText
            });
        }, this);
    },
    render: function() {
        return (
            <p>{this.state.text}</p>
        );
    }
});

React.renderComponent(
    <TextBox model={model} />,
    document.getElementById('view-holder')
);

As I said this does work as intended. The view re-renders whenever the model's text property changes. Would this be considered "Good" React code, or should I hook this up differently?

发布评论

评论列表(0)

  1. 暂无评论