ProductiveRage / Bridge.React

Bindings for Bridge.NET for React - write React applications in C#!
MIT License
74 stars 14 forks source link

ReactElementList possible broken #27

Closed AleXr64 closed 7 years ago

AleXr64 commented 7 years ago
       public class TstItem
            {
                public string ActToGo;
                public string TextToShow;
            }

    public static class TstItemsArray
            {
                public static TstItem[] arr =
                    {
                        new TstItem {ActToGo = "doOne", TextToShow = "First Item"},
                        new TstItem {ActToGo = "doSecond", TextToShow = "Second Item"}
                    };
            }

        public class TestItem : StatelessComponent<TestItem.Props>
            {
                public TestItem(Props props, params Union<ReactElement, string>[] children) :
                    base(props, children) { }

                public override ReactElement Render()
                    {
                        return DOM.Div(props.Content);
                    }

                public class Props
                    {
                        public string act;

                        public string Content;
                    }
            }

        public class Test : Component<Test.Props, Test.State>
            {
                public Test(Props props, params Union<ReactElement, string>[] children) :
                    base(props, children) { }

                public override ReactElement Render()
                    {
                        var result = ReactElementList.Empty;
                        foreach(var item in props.items)
                            result.Add(new TestItem(new TestItem.Props
                                {
                                    act = item.ActToGo,
                                    Content = item.TextToShow
                                }));
                        return DOM.Div(result);
                    }

                public class Props
                    {
                        public TstItem[] items;
                    }

                public class State
                    {
                        public string Active;
                    }
            }

        public class App
            {
                public static void Main()
                    {
                        React.Render(new Test(new Test.Props
                                         {
                                             items = TstItemsArray.arr
                                         }),
                                     Document.GetElementById("test"));
                    }
            }

This code returns single blank DIV without creating "TestItem" components. What I'm doing wrong?

AleXr64 commented 7 years ago
        public class Test : StatelessComponent<Test.Props>
            {
                public class Props
                    { }

                public Test(Props props, params Union<ReactElement, string>[] children) : base(props, children) { }
                public override ReactElement Render()
                    {
                        var result = ReactElementList.Empty;
                        result.Add(DOM.Div("Test"));
                        return DOM.Div(result);
                    }
            }

        public class App
            {
                public static void Main()
                    {
                        React.Render(new Test(null),
                                     Document.GetElementById("test"));
                    }
            }

Hmm... I'm really doing something wrong, because this code returns div without childs too. How I must use ReactElementList?

dionrhys commented 7 years ago

ReactElementList is an immutable list class, so calling the Add method on it doesn't change the existing list. Instead, it returns a new list with the added item.

So change your code to this: (note the result = result.Add(...) bit)

public override ReactElement Render()
{
    var result = ReactElementList.Empty;
    foreach (var item in props.items)
        result = result.Add(new TestItem(
            new TestItem.Props
            {
                act = item.ActToGo,
                Content = item.TextToShow
            }
        ));
    return DOM.Div(result);
}

You can use LINQ instead if you wanted:

public override ReactElement Render()
{
    return DOM.Div(
        props.items.Select(item => new TestItem(
            new TestItem.Props
            {
                act = item.ActToGo,
                Content = item.TextToShow
            }
        ))
    );
}
ProductiveRage commented 7 years ago

That's right. You need to use the return value of "Add".