3

I am building a feed with ReactJS.NET but have problems with a error that chromes gives me.

When page is loaded I can see 1 error

Uncaught ReferenceError: FeedBox is not defined (anonymous function)

its thrown from the React.render line :

    <script src="http://fb.me/react-0.12.2.js"></script>
    <script src="/Scripts/jquery-2.1.3.min.js"></script>
    <script src="/Scripts/spin.min.js"></script>
    <script type="text/jsx" src="/Scripts/JSXTransformer.js"></script>

    <script>React.render(React.createElement(FeedBox, {"controlId":"myFeedBox","initialData":{"TopicList":[{"Id":null,"UserInfoUrl":"http://www.bradspel.net","UserName":"Carl","UserPicSrc":"http://www.bradspel.net/tools/avatars/15_avatar.jpg","LikeCount":487,"Like":false,"CommentCount":3,"DateCreated":"2015-02-22 19:42:59","DateEdit":"2015-02-22 19:42:59","Message":"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus","Comments":[{"Id":null,"UserInfoUrl":"http://www.bradspel.net","UserName":"Carl","UserPicSrc":"http://www.bradspel.net/tools/avatars/15_avatar.jpg","LikeCount":56,"Like":false,"CommentCount":3,"DateCreated":"2015-02-22 19:42:59","DateEdit":"2015-02-22 19:42:59","Message":"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus","Comments":[]}]}],"UserId":5},"pageNr":1,"pageTake":25,"maxPageNr":0}), document.getElementById("react1"));
</script>

The component FeedBox is however rendered correcly but the onClick do not work.

The Index looks like this :

    @{
        ViewBag.Title = "Index";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }

    @section MainContainer
    {
        <h2>Index</h2>

        @Html.React("FeedBox", new
        {
            controlId = "myFeedBox",
            initialData = Model.FeedModel,
            pageNr = 1,
            pageTake = 25,
            maxPageNr = 0
        })
    }

Feed.jsx

var LikeCon = React.createClass({
    handleClick: function(like) {
        alert("like : " + like);
      },
    render(){
        return this.renderLikeButton(this.props.like, this.props.likeCount, this.props.userId)
    },
    renderLikeButton(like, likeCount, userId){
        return (
                content =  
                <div className="likeCon">
                    <div className={like==true ? "likeButConAct" : "likeButCon"}>
                        <div className="likeB" onClick={this.handleClick.bind(this,!like)} >
                            &nbsp;
                        </div>
                        { likeCount > 0 ? <div className="likeCount">{likeCount}</div>: null}

                    </div>
                </div>
            );
    }
});


var TopicComments = React.createClass({
    render: function() {
        var comment = this.props.data.map(function(com, i) {
            return (
            <article>
            <div className="comment">
                <div className="tUImgLnk">
                    <a title={com.UserName} target="_blank" href={com.UserInfoUrl}>
                        <img className="tUImg" src={com.UserPicSrc} />
                    </a>
                </div>
                <a href="#" target="_blank">{com.UserName}</a>
                <div className="content">
                    {com.Message}
                </div>
                <div className="status">
                    <div className="dateCreated dimText">
                        {com.DateCreated}
                    </div>  
                    <LikeCon like={com.Like} likeCount={com.LikeCount} objectId={com.Id} categoryKey={1} userId={this.props.userId} />
                    <article></article>
                </div>
            </div>
            </article>);
        }.bind(this));
        return(
            <div className="comments">
                {comment}
            </div>
            );
    }
});


var CommentForm = React.createClass({
  handleSubmit: function(e) {
    e.preventDefault();
    var author = this.refs.author.getDOMNode().value.trim();
    var text = this.refs.text.getDOMNode().value.trim();
    if (!text || !author) {
      return;
    }
    this.props.onCommentSubmit({Author: author, Text: text});
    this.refs.author.getDOMNode().value = '';
    this.refs.text.getDOMNode().value = '';
    return;
  },
  render: function() {
    return (
      <form className="commentForm" onSubmit={this.handleSubmit}>
        <input type="text" placeholder="Your name" ref="author" />
        <input type="text" placeholder="Say something..." ref="text" />
        <input type="submit" value="Post" />
      </form>
    );
  }
})

var FeedTopic = React.createClass({
        render: function() {
            return (
                <div className="topic">
                    <div className="tBack">
                        <div className="tHead">
                            <div className="tUImgLnk">
                                <a title={this.props.data.UserName} target="_blank" href={this.props.data.UserInfoUrl}>
                                    <img className="tUImg" src={this.props.data.UserPicSrc} />
                                </a>
                            </div>
                            <div className="tInfo">
                                    <h4 className="nLnSpc margB3p"><a title={this.props.data.UserName} target="_blank" href={this.props.data.UserInfoUrl}>{this.props.data.UserName}</a></h4>
                                    <span className="dimText" >{this.props.data.DateCreated}</span>
                            </div>
                        </div>
                        <article></article>
                        <div className="tContent">
                            {this.props.data.Message}
                        </div>
                        <LikeCon like={this.props.data.Like} likeCount={this.props.data.LikeCount} userId={this.props.userId} />
                        <article></article>
                    </div>
                    <TopicComments data={this.props.data.Comments} userId={this.props.userId} />
                    <CommentForm />
                </div>

            );
        }
});


var FeedList = React.createClass({
    render: function() {
        var userId = this.props.data.UserId;
        var controlId = this.props.controlId;
        if(this.props.data.TopicList != null && this.props.data.TopicList.length > 0){
                var topic = this.props.data.TopicList.map(function (topic, i) {
                    return (
                        <FeedTopic data={topic} key={i} userId={this.props.data.UserId} />
                    );
                }.bind(this));
            }
        return (
            <div className={controlId}>
                {topic}
            </div>
        );
    }
});



var FeedBox = React.createClass({
    getInitialState: function() {
            return { data: this.props.initialData };
     },
    render: function(){
        return (
            <FeedList data={this.state.data} controlId={this.props.controlId} />

        );
    }
});

_Layout

@using System.Web.Optimization
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title - Bradspel.net</title>
    @Styles.Render("~/Content/css")

    @RenderSection("Header", required: false)
</head>
<body>
    <div id="header">
        @RenderBody()
    </div>
    <div id="mainContent">
        <div id="page">
            @RenderSection("MainContainer")
        </div>
    </div>
    <script src="http://fb.me/react-0.12.2.js"></script>
    <script src="@Url.Content("~/Scripts/jquery-2.1.3.min.js")"></script>
    <script src="@Url.Content("~/Scripts/spin.min.js")"></script>
    <script type="text/jsx" src="@Url.Content("~/Scripts/JSXTransformer.js")"></script>

    @Html.ReactInitJavaScript()
</body>
</html>

ReactConfig

public static class ReactConfig
    {
        public static void Configure()
        {
            ReactSiteConfiguration.Configuration
                .AddScript("~/Scripts/Grid.jsx")
                .AddScript("~/Scripts/Feed.jsx");
        }
    }
Banshee
  • 15,376
  • 38
  • 128
  • 219
  • Can you confirm that the JavaScript for `Feed.jsx` is actually downloaded to the client (using the network tab)? It's not obviously included in the first snippet. – WiredPrairie Feb 22 '15 at 19:23

1 Answers1

4

You don't need to use JSXTransformer client-side with ReactJS.NET. All JSX transformation is done server-side, so you can remove the JSXTransformer script.

The issue here is that you're not referencing the JSX files in your HTML. The files listed in ReactConfig.cs are only for server-side rendering. For client-side rendering, you still need to add a <script> tag for these files. This is not done automatically as different people use different configurations (eg. different minifiers). You can reference the JSX files directly; ReactJS.NET will transform them to JavaScript and cache them on-the-fly:

<script src="@Url.Content("~/Scripts/Grid.jsx")"></script>
<script src="@Url.Content("~/Scripts/Feed.jsx")"></script>

This is good for development, but for a production site you'll probably want to use a bundler/minifier like Cassette or ASP.NET Bundling and Minification (which are both native to .NET), or Webpack or Gulp (which are Node.js tools). The documentation on the ReactJS.NET site has pages on how to configure all these tools.

Daniel Lo Nigro
  • 3,346
  • 27
  • 29
  • Thanks, in my case the solution was to remove the type="text/jsx" attribute form the script tag referencing my .jsx component – trevorgk Apr 12 '15 at 22:59