Skip to content
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

[CS2] JSX documentation, Try CoffeeScript improvements #4583

Merged
merged 9 commits into from
Jun 26, 2017

Conversation

GeoffreyBooth
Copy link
Collaborator

@GeoffreyBooth GeoffreyBooth commented Jun 20, 2017

Adds a “JSX” section to the docs, and a note about the < and > operators to the breaking changes. Follows #4551. @xixixao, would appreciate your review.

https://rawgit.com/GeoffreyBooth/coffeescript/2-docs/docs/v2/#jsx

I also added some features to Try CoffeeScript to make it more similar to the Babel REPL. Now location.hash is set automatically whenever the code recompiles, and the Link button has been removed. We also save the user’s code automatically into localStorage, so it’s there the next time they return.

I also fixed (I hope) the code editors’ handling of tab-indented code, to avoid “inconsistent indentation” errors. The editors will always indent with two spaces by default; only if you paste in tab-indented code will they behave in tab-indented mode. Once at least one line in the code block begins with a tab, the tab key indents with tabs and the enter key causes new lines to be tab-indented. @lydell, @jashkenas, any notes?

@GeoffreyBooth GeoffreyBooth added this to the 2.0.0 milestone Jun 20, 2017
@GeoffreyBooth GeoffreyBooth changed the title [CS2] JSX documentation [CS2] JSX documentation, Try CoffeeScript improvements Jun 21, 2017

[JSX](https://facebook.github.io/react/docs/introducing-jsx.html) is JavaScript containing interspersed XML elements. While conceived for [React](https://facebook.github.io/react/), it is not specific to any particular library or framework.

CoffeeScript supports interspersed XML elements, without the need for separate plugins or special settings. The XML elements will be rendered as such, outputting JSX that could be parsed like any normal JSX file, for example by [Babel with the React JSX transform](https://babeljs.io/docs/plugins/transform-react-jsx/). CoffeeScript does _not_ output `React.createElement` calls or any code specific to React or any other framework. It is up to you to attach another step in your build chain to convert this JSX to whatever function calls you wish the XML elements to compile to.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The XML elements will be rendered compiled

Otherwise lgtm.

<Star className="halfStar" />}
{for emptyStar in [Math.ceil(rating)...maxStars]
<Star className="emptyStar" key={emptyStar} />}
</aside>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the example, but note that it doesn't fit well on relatively normal sized screen:
screen shot 2017-06-24 at 19 30 33

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only the second line wraps, which I don’t think is such a big deal.

@GeoffreyBooth
Copy link
Collaborator Author

Just going to merge this in, if anyone else has any more notes please feel free to comment and I’ll make the changes as part of the next release docs.

@GeoffreyBooth GeoffreyBooth merged commit 1f31073 into jashkenas:2 Jun 26, 2017
@GeoffreyBooth GeoffreyBooth deleted the 2-docs branch June 26, 2017 06:53
@GeoffreyBooth GeoffreyBooth mentioned this pull request Jun 30, 2017
@MaxPleaner
Copy link

MaxPleaner commented Aug 3, 2017

Finally got around to trying React, and noticed one improvement of the Coffeescript code over ES6 - namely, the ability to bind instance methods to the instance when making a class definition.

For example, in the react docs on event handling, they have this example:

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};
    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }
  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

the line this.handleClick = this.handleClick.bind(this); is necessary because ES6 doesn't support bound instance methods, so far as I'm aware, without extensions.

With Coffeescript this could be written as:

class Toggle extends React.Component
  constructor: (props) ->
    super(props)
    @state = isToggleOn: true
  handleClick: => # get to use arrow function here
    @setState (prevState) => isToggleOn: !prevState.isToggleOn
  render: -> (
    <button onClick={@handleClick}>
      {@state.isToggleOn ? 'ON' : 'OFF'}
    </button>
  )

So, it's nice that instance methods can be easily bound in Coffeescript using arrow functions.

This is just an idea for another example. I was reading through the longer discussions on CSX and remember there was interest in getting ideas for examples that show coffeescript's strengths.

@GeoffreyBooth
Copy link
Collaborator Author

That’s a great point. Is there a place to include that in the docs, without the docs getting too long?

@MaxPleaner
Copy link

maybe there could be a separate section about react in coffeescript, which shows a slightly larger code snippet, for a todo app or something.

I got this simple counter-incrementor working in React Native, for example. Granted, it's pretty straightforward and not really doing anything really fancy with Coffeescript other than using its basic syntax.

CounterButton = ({text, on_press}) ->
  <Button title='counter' onPress={on_press}>{text}</Button>

CounterValue = ({value}) ->
  <Text>{value}</Text>

class Counter extends React.Component
  constructor: (props) ->
    super(props)
    @state = counter_val: 1
  increment_counter: =>
    @setState (old_state) ->
      counter_val: old_state.counter_val + 1
  render: ->
    <View>
      <CounterButton
        on_press={@increment_counter}
        text='increment counter'
      />
      <CounterValue value={@state.counter_val} />
    </View>

What took me a little while to realize, though, is the fact that Coffeescript's JSX supports a wider range of things inside {} tags, since everything is an expression. React's docs, for example, say that if is not allowed, but Coffee can do it. That might be worth re-iterating in the existing example's intro.

@GeoffreyBooth
Copy link
Collaborator Author

I was hoping to link to a few repos with example projects. Could you maybe post this as its own project with a README and I could link to it? It would be nice to have something that people could clone and get running in just a few steps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants