react

package module
v0.0.0-...-03f3735 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 27, 2015 License: MIT Imports: 4 Imported by: 0

README

go-react

A series of highly experimental GopherJS bindings for React.js.

Tests and benchmarks are absent until the proof of concept is more fleshed out, both in Go and React. The API is likely to change randomly and with great malice.

In short, until becnhmarks are implemented we can't know if this is feasible. So no, this is not ready for production. No, this is not ready for funzies. No, this is probably not ready for anything yet.

Examples

A series of proof of concept examples, which match React docs examples/tutorials, can be found in the _examples directory

Goals

  1. Abstract away all *js.Object and interface{} tomfoolery from GopherJS. Nice Go types and interfaces, all around.
  2. Translate React-centric design elements to a more Go oriented design.
  3. Provide a familiar API to create React components, while adhereing to goal #2.

Installation

Did you not read before? Don't use this!

FAQ

Q: Can i use this in the browser?

Yup! Just make sure a global react library object is available.

Q: What about CommonJS?

Support for CommonJS (Node/Webpack/etc) will be coming in the near future. Once the PoC is more fleshed out.

Q: How's the performance?

A: Truthfully, no clue. I've not done any benchmarks at this point. I expect some loss due to the overhead of GopherJS, but my hope is that if we only create simple (small surface) objects and pass them to React, it won't know the difference.

If React doesn't experience anything different from a "normal" environment, we may not have large losses.

Just make sure to follow GohperJS' performance tips.

Q: Didn't someone already try this?

A: Yup, and gave up. Unforutnately they removed their efforts from Github, so it's hard to say what exactly was done right, or wrong.

It also helps that i do not expect to succeed. I expect this to fail, somehow. And if this ends up working, win win right?

Q: Why not a pure GopherJS Framework?

A: That would likely be far better, you are correct. Unfortunately GopherJS is quite young, and pure GopherJS frameworks are even more young. I wanted to use Go with a well vetted clientside framework, one that we trust and love. React certainly fits that description, though it's design may prove difficult to map GopherJS to.

Don't forget to checkout Frameworks using GopherJS.

Q: Oh god why

A: I know right?

Q: No seriously, why Go + React?

A: This project spawned as need to prove that it's not possible. I was writing a pipeline for FlowType and BabelJS, and adding in linting, formatting, and etc. All with the goal of making writing JS nice and scalable for large projects (mainly via FlowType's type checking).

After writing a rather complex and fragile pipeline to handle all of that stuff, it hit me. Why am i trying so hard to bend JavaScript to my needs? FlowType is great and all, but it's a young project so there are a lot of rough edges with supporting tools.

Go on the otherhand, has all the nicities i love, it's a great language, and is what i'm already writing the backend in.

I'm not a believer in the holy grail of writing one language on all platforms. I have no motivations for that here. I simply want a nicely typed language with features and good tooling. Go achieves that.

Q: But I love JS || Flow || Babel!

A: Great, stick with JS || Flow || Babel! You'll get better performance than you'll see here anyway :)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RenderToDomId

func RenderToDomId(c Component, domId string) error

Types

type Class

type Class func(Props, ...Component) Component

Class is a function that takes Props and Components, returning a new Component. It does not provide the actual implmentation of a Component, but rather it is a loose specification to easily create instances of components.

In other words, you should create a function for each of your components, with your desired component name for users of your component to cleanly create instances of it.

To go into rather absurd detail, lets look at some examples. In essence, a Class is similar to JSX. In JSX, we could use:

<div></div>

To create a div instance. In go-react, we would use:

Div()

Still not clear?, lets say we have a hand made html Component. It may look something like this:

type Div struct {
	props    Props
	children []Component
}
func (c *Div) Render() []Component {
	return c.children
}
func (c *Div) Tag() string { return "div" }
func (c *Div) Props() string { return nil }
func (c *Div) Content() string { return "" }

If we had a whole series of html elements like this, and wanted to initialize them for actual use, it might look like this:

Div{props: nil, children: []Component{
	Header{props: nil, children: []Component{
		H1{props: Props{"className": "title"}, children: []Component{
			Span{props: nil, []Component{react.Content("My Website!")}},
			},
		},
		Ul{props: nil, children: []Component{}},
	}
}

Now lets compare this to what the JSX would look like:

<div>
	<header>
		<h1 className="title">
			<span>My Website!</span>
		</h1>
		<ul></ul>
</div>

The JSX presents a far more readable representation of the given components. To emulate that nice JSX, we can create functions that initialize our Go Components. Visually, it will look far closer to the JSX. Example:

Div(nil,
	Header(nil,
		H1(react.Props{"className": "title"},
			Span(nil, react.Content("My Website!")),
		),
		Ul(),
	),
)

Both of the Go examples create the same Components, they're just presented in a much cleaner way. By providing a function of type Class for your own Components, you can drastically improve the cleanliness of your component creations.

var (
	Div      Class = HtmlFactory("div")
	Span     Class = HtmlFactory("span")
	P        Class = HtmlFactory("p")
	Ol       Class = HtmlFactory("ol")
	Ul       Class = HtmlFactory("ul")
	Li       Class = HtmlFactory("li")
	H1       Class = HtmlFactory("h1")
	H2       Class = HtmlFactory("h2")
	H3       Class = HtmlFactory("h3")
	H4       Class = HtmlFactory("h4")
	H5       Class = HtmlFactory("h5")
	H6       Class = HtmlFactory("h6")
	Button   Class = HtmlFactory("button")
	Code     Class = HtmlFactory("code")
	Pre      Class = HtmlFactory("pre")
	Textarea Class = HtmlFactory("pre")
	Form     Class = HtmlFactory("form")
	Em       Class = HtmlFactory("em")
	Strong   Class = HtmlFactory("strong")

	// TODO: Implement special common options into the (not)Class func.
	A Class = HtmlFactory("a")
)

func FuncClass

func FuncClass(fn func(Component) Component) Class

func HtmlFactory

func HtmlFactory(tag string) Class

HtmlFactory is an easy func for creating plain Tag classes. This is used to create the entire base suite of Html Components in the react package.

type Component

func Content

func Content(s string) Component

Content is a special Class that accepts a string and returns a component that will return the given string via `Content()`.

For further explanation of this quirky Class, see the Content() docstring of the Component interface.

type Components

type Components []Component

type Props

type Props map[string]interface{}

func (Props) ClassName

func (p Props) ClassName() (s string, ok bool)

func (Props) GetBool

func (p Props) GetBool(key string) (v bool, ok bool)

func (Props) GetString

func (p Props) GetString(key string) (v string, ok bool)

type This

type This struct {
	// contains filtered or unexported fields
}

func (*This) Children

func (t *This) Children() Components

func (*This) ComponentDidMount

func (t *This) ComponentDidMount()

func (*This) ComponentWillUnmount

func (t *This) ComponentWillUnmount()

func (*This) Content

func (t *This) Content() string

func (*This) ForceUpdate

func (t *This) ForceUpdate() error

TODO: (Maybe) Add a callback to the js.Call, and block for it's return. Why maybe? Well, the blocking call may not be worth it. Especially if ForceUpdate ends up being how we render in go-react

func (*This) Props

func (t *This) Props() Props

func (*This) Render

func (t *This) Render() Component

func (*This) SetThis

func (t *This) SetThis(this *js.Object) error

func (*This) Tag

func (t *This) Tag() string

Directories

Path Synopsis
_examples
components
This Go package is comparable to the following React JSX: var CommentList = React.createClass({ render: function() { return ( <div className="commentList"> Hello, world! I am a CommentList.
This Go package is comparable to the following React JSX: var CommentList = React.createClass({ render: function() { return ( <div className="commentList"> Hello, world! I am a CommentList.
hello
This Go package is comparable to the following React JSX: React.render( <h1>Hello, world!</h1>, document.getElementById('example') );
This Go package is comparable to the following React JSX: React.render( <h1>Hello, world!</h1>, document.getElementById('example') );

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL