This month I started a new React-Native project and used some libraries I heard only good things about in the last 12 months or so. While writing my app, I couldn't help to notice all the new syntax that crept into my code.
First, that standard JavaScript stuff. In the last years it accumulated many new things like destructuring or async/await. Even a simple example like this would seem completely foreign to a new developer:
const {token, type} = await callApi();
This would have been written differently a few years ago, before ES2015 and promises:
callApi(function(response) {
var token = response.token;
var type = response.type;
})
And as I said, this is just a simple example of an everyday API call.
Then we got JSX, which is the default way to do markup in React and also React-Native. It basically compiles down to React.createElement({...})
calls, but it looks like something is seriously wrong with the JavaScript. I mean, after years of doing React it doesn't seem so bad to me anymore and you find your markup rather fast in the code, but well, you have to learn how it works too. Other frameworks use a templating language like Handlebars, which takes the new concepts to another level, haha.
So you write something like this to create a component:
const MyComponent = props => (
<View>
<Text>Hello!</Text>
<Image src={require(...)} />
</View>
);
Instead of this:
var MyComponent = function MyComponent(props) {
return React.createElement(View, null,
React.createElement(Text, null, "Hello!"),
React.createElement(Image, { src: require(...) })
);
};
And this is what you write multiple times a day creating a React application.
Next there is CSS or should I say CSS-in-JS? Using styled-components to style your React components is the way to go now and it uses yet another new feature to get CSS into JS, tagged template literals.
const DangerText = styled.Text`
backgroundColor: red;
color: white;
fontWeight: bold;
`;
Instead of something like this:
const style = {
backgroundColor: "red",
color: "white",
fontWeight: "bold"
};
const DangerText = props => <Text style={style} {...props} />;
Then there is GraphQL, the new fancy way to create HTTP APIs. Don't be fooled by my sarcasm, it really is a nice way to build APIs and I think it is much better than REST, but... whelp... it comes with its own query language, leveraging the tagged template literals too.
const query = gql`
{
user(id: 5) {
firstName
lastName
}
}
`;
And finally, lets get the whole thing statically type checked with the help of Flow.
function doSomething(func: <T>(param: T) => T) {
}
Yes, I know, we had CSS, HTML, JS and SQL back in the days and besides some new JS features and the GQL syntax, there isn't much fundamentally new happening here, but I have to admit, it could be quite an effort to dive into such a codebase when you just learned JavaScript or even if you had a few years pause since your last JavaScript stint.
Is this really the way to go? Should we do things more idiomatically with JavaScript? More object-literals instead of CSS? More HyperScript instead of JSX? I don't know if this would be better, but it would reduce the used concepts quite a bit.
Top comments (11)
Nice article!
Quick tip: In your pre-ES2015 callApi() example,
token
andtype
would have to be defined above the function call, to be equivalent to the first version.Otherwise they exist only inside your callback. ;)
e.g.:
The thing is that you can't use
token
andtype
in the body of the caller of callApi bc you don't know if the callback was called and it's side-effects were produced.While reading this post I started justifying each design choice in my head... I've turned into the slowly boiling frog! I love all these new language features, but you're right; modern JS feels like regional dialects sometimes. It's absurd, but so is the complexity that web developers manage, so I'm not sure what the answer is.
I've experienced a similar feeling with tooling; I enjoy using Babel, Flowtype, Eslint etc. and am annoyed when I can't use them, but I'm also annoyed when I have to set them up for a new project.
It's nice to see how less alone I am with this concern. 17 years in, and I have never struggled so much with JavaScript, if you can call it that.
I see what you're saying. And I'll agree, having not done any serious web dev between 2007 and 2013 when I started picking up Node, it felt like a completely different language. But I don't think that was a result of the syntax as much as the ideas: jQuery was no longer cool, DHTML was no longer a word, XHTML which was supposed to be the future had withered, and everyone used JSON instead of XML. Oh, and bundlers. And modules. It has literally taken me years, working full time on JavaScript projects since 2014, to feel like I've caught up. I started using async/await a few months ago, and have yet to use React in a project. But it's not the syntax that holds me back I don't think. If anything, the syntax (arrow functions, JSX, async/await) help make code more readable. We just live in such a fertile time for programming languages and ideas (and aren't framework just manifestations of an idea?) are being introduced at a manic pace.
That's why I really enjoy the VueJS library. It doesn't force any languages, you can still write your code in plain ES5, HTML and CSS but you are free to use Coffeescript, JSX, Stylus or whatever floats your boat.
Mimimimimi...
Don't hate :D
Like I wrote, I choose this stuff all by myself and use it everyday, it's not that hard, but I also have 10 years experience. Maybe doing things a bit more junior dev friendly could reduce the entry to such codebases.
That happened to me! I started to work with modern JS ≈ a year ago and the first few months i hated furiously all the syntactic sugar that was added (even when i love to tinker with weird toy langs).
Those months passed and now i can't imagine to not use Promises, arrow funcs and a lot of the things that where borrowed from the FP world. I think that syntactic sugar is really helpful when you can understand it, but at first glance is just magic, and magic code is really hard yo understand (and make relevant tests with that understanding).
Schön gesagt xD