Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement] Copy react native JSX programming style. #286

Closed
Jonatthu opened this issue Dec 11, 2020 · 7 comments
Closed

[Enhancement] Copy react native JSX programming style. #286

Jonatthu opened this issue Dec 11, 2020 · 7 comments

Comments

@Jonatthu
Copy link

This would require a new syntax for vscode and a new transpiler BUT it is worth it!

I imagine c# component classes with dependency injection and a method called render and jsx like XML but using c# and dotnet 5/6!

It would be really nice

@GeraudFabien
Copy link

Why would it be "really nice" to someone that never done React native before. What the goal? How?
Can you explain what is you're current problem?

Seems like you are used to react native. And ask "Can you transform everything's else in react native this way i can do any thinks without learning?". But most of the people are not used to React native. Or don't thinks it's a great. What about them?

@Jonatthu
Copy link
Author

The first platform to success in cross-platform development in terms of usage, number of contributions and community is react native, they are doing something great, c# is my preferred language and as I said, by copying the programming style language of JSX would not break the "regular" programming style designed for maui sr. @GeraudFabien
It would be an "optional" feature that I think would be really good to migrate a lot of developers coming from react native to maui. EVEN microsoft develops with react native so I THINK this would be KEY feature to BRING community like me.

:D

@GeraudFabien
Copy link

Sorry i thinks there is a misunderstanding. I'm not against or poor the idea I just want to know why and how. If you could get a sample on what you want. Or a big key feature (dependency injection and a method called XXX that render is not really new to C#, so i assume jsx like XML). But i assume if you say "Like" it means you don't ask for exactly the same...

The first platform to success in cross-platform development in terms of usage, number of contributions and community is react native

This doesn't mean everyone like it. And most develop in other tool. I barely tryed it so i just want to understand what's you want (Native, Bindind, css like styling).

@redradist
Copy link

This would require a new syntax for vscode and a new transpiler BUT it is worth it!

I imagine c# component classes with dependency injection and a method called render and jsx like XML but using c# and dotnet 5/6!

It would be really nice

@Jonatthu It is not worth it ... Look at Blazor mobile binding, it is already jsx like approach but better because you do not have such mixing of code and markup

@Jonatthu
Copy link
Author

@redradist It is not about what it is "better", since many BIG companies including microsoft did not doubt in jump into react native (: It is about that I like c# and would like to see my react native apps on c#... I have many in app store and I can tell that I love react native but not too much javascript :) I rather prefer c#, and I know many people on the community that prefers c# as well. Anyways even without this feature ONLY time would tell what's better or not. Sometimes is about community and speed to deliver something...

@GeraudFabien
Copy link

It is not about what it is "better"

Yes that why i ask for the goal/Problem/Case this issue want to solve. If the goal is Help web developper use xamarin or fill the gap between Xamarin and blazor to have just the UI part diffrents but with the same code look and feel (XML/Binding style/CSS CF. Mobile blazor binding).

BIG companies including microsoft did not doubt in jump into react native (:

Big company use evrythinks. as they are big they have small, medium and big project and most doesn't want to depend on one technology only.
React native isn't new or old (5 year) and i don't feel like there i a lot of people using it. there is not a lot of developer or project.

@Jonatthu Again if you don't give a sample or a lengthly explaination about what you want we can't know what you are asking for. What part do you want to "Copy" is it a feature? If you want full ract native with C# backend it's a totally different project. It may be possible to do some thinks with WASM (1, 2, 3). But this has nothinks to do with maui.

@alfosua
Copy link

alfosua commented Jan 12, 2021

I think that the upcoming MVU-pattern could offer some basis in the way how we can achieve this, or at least, for functional-based development with React. Instead of explicitly copying JSX, we can do somewhat like a CXX (Csharp Xaml eXpressión, I'm open to any other name). It may decrease the learning curve, not just for React/React Native developers, but pretty much any new one. It admit that I found React plus JSX as an easy-to-learn pattern.

Let me refactor the MVU example from this post to look at how it could seem. First, this example is more based on JSX patterns:

private readonly State<int> count = 0;

Component Render() =>
    <StackLayout>
        <Label>Welcome to .NET MAUI!</Label>
        <Button OnPress={ () => count.Value++ }>
            You clicked { count } times.
        </Button>
    </StackLayout>

This might be more according with XAML syntax:

private readonly State<int> count = 0;

Component Render() =>
    <StackLayout>
        <Label Text="Welcome to .NET MAUI!" />
        <Button Text="You clicked { count } times."
                      Command={ () => count.Value++ } />
    </StackLayout>

Notice I did not use string interpolation in the Label's property Text="You clicked { count } times.", because it should not be necessary inside a CXX. Any curly-braces should mean a C# pure expression.

Also notice that this code is inside a normal C# file (with a .cs extension), and it is inside a typical class.

// I am the YouSolution/Components/Example.cs
using Microsoft.Maui;
using Microsoft.Maui.Cxx;

public class Example : Component
{
    private readonly State<int> count = 0;
 
    Component Render() =>
        <StackLayout>
            <Label Text="Welcome to .NET MAUI!" />
            <Button Text="You clicked { count } times."
                          Command={ () => count.Value++ } />
        </StackLayout>
}

The Component and State classes in this case comes from Microsoft.Maui.Cxx. And CXX code will only be available if using the Microsoft.Maui.Cxx namespace, or if the filename have the .cxx extension (which implicitly compiles with such using statement).

I will prefer to just adopt the Render implementation from the old React API for class-based components. Implementing the other stuff that the React.Component class does will seem redundant and unnecessary when having the powerfulness of hooks. Something that I'm sure C# can accomplish very well. I would rather prefer focusing on supporting functional-components over classy-components. Anyway, keeping both is wise.

Let me try to showcase some ideas that could fit with the C# syntax:

In YourSolution/Components/CustomButton.cxx :

[PropertyTypes(typeof(Button))]
public class CustomButton : Component
{
    // We can use public automatic properties to passing them through XAML 
    public Rect ContainerPadding { get; set; }

    public Component Render() =>
        <Container Padding={ ContainerPadding }>
            <Button Text={ Text } />
        </Container>
}

In YourSolution/Components/CustomLabel.cxx :

public class CustomLabel : Component
{
    public class PropertyTypes : Label.PropertyTypes
    {
        public Rect ContainerPadding { get; set; }

        public Builder<PropertyTypes> Configure(Builder<PropertyTypes> builder) =>
            builder.InheritsFrom<Label.PropertyTypes>()
                .And.Property(pt => pt.ContainerPadding)
                    .HasDefaultValue(new Rect(10));
    }

    public Component Render() =>
        <Container Padding={ ContainerPadding }>
            <Label Text={ Text } />
        </Container>
}

In YourSolution/Component/ComponentLibrary.cxx:

public static class ComponentLibrary
{
    // I may prefer to use PascalCase for functional component parameters (which are properties)
    public Component MyStatelessFunctionalComponent(int ValueA, int ValueB) =>
        <CustomLabel Text="{ ValueA } + { ValueB } = { ValueA + ValueB }" />

    // Component already implements the Children property
    public Component MyWrapperFunctionalComponent() =>
        <Container>
            { Children.Cast<Label>()
                .Select(x => <CustomLabel Text={ x.Text }/>) }
        </Container>

    public Component MyStatefulFunctionalComponent(int ValueA, int ValueB)
    {
        // I don't know if this is factible
        State<int> multiplier = 1;

        Action onIncrease = () => { multiplier.Value++ };
        Action onDecrease = () => { multiplier.Value-- };

        return (
            <MyWrapperFunctionalComponent>
                <Label Text="Current multiplier: { multiplier }" />
                <MyStatelessFunctionalComponent
                    ValueA={ 2 * multiplier } ValueB={ 4 * multiplier }
                 />
                <CustomButton Text="Increase multiplier" Command={ onIncrease } />
                <CustomButton Text="Decrease multiplier" Command={ onDecrease } />
            </MyWrapperFunctionalComponent>
        );
    }
}

And so, and so... Of course this would need of a great support from the compiler. But it is something that is possible.

Note: I may need to fix some identation. Sorry, the built-in Github text editor isn't so helpful for code...

@PureWeen PureWeen closed this as completed Feb 1, 2021
@dotnet dotnet locked and limited conversation to collaborators Feb 1, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Projects
None yet
Development

No branches or pull requests

5 participants