Show HN: React patterns, techniques, tips and tricks
github.com
github.com
> setState() in componentWillMount()
componentWillMount() is an anti-pattern. It is not a true lifecycle hook. It is invoked on the server, unlike componentDidMount and friends. Anything you do here can, and perhaps should, be done in the constructor.
> Mutating State without setState()
handleClick() {
// BAD: We mutate state here
this.state.items.push('lorem');
this.setState({
items: this.state.items
});
}
There's no explanation as to why this is bad, just that it's bad and you shouldn't do it. Because.The real reason, in this particular example, is that any lifecycle hooks that rely on comparing two consecutive versions of the state will not work, because the older version of the state will have been mutated.
> Using indexes as keys... Bad... This limits the optimizations that React can do.
> Good... React would be able to reorder elements without needing to reevaluate them as much.
This isn't any incentive at all. I don't do premature optimizations and so I'd happily use key={index} if optimization was the only issue and performance didn't suck.
The real incentive to use a value that uniquely identifies the entity being rendered as the key, rather than an index, is to prevent the representation of entities from being removed and added back to the DOM, so I can animate their addition and removal, via CSS transitions, when they are actually added and removed. Using the index as the key would make the wrong elements animate. Also, I wouldn't want certain elements to unnecessarily go through the end of their lifecycle only to be created again, especially if their lifecycle hooks are tied to various side effects (e.g. API endpoints being called).
0: https://github.com/reactjs/react-redux/issues/129
Edit: You might call dispatching in a constructor an anti-pattern (or having any side-effects at all), but quite a few people do it and it can cause very subtle bugs that aren't entirely reproducible.
That's probably a simplistic example, but it really does happen.
If anyone's interested, my React/Redux links list [0] points to a variety of other useful articles for various React techniques, such as the "React Component Patterns" [1] and "React Component Composition" [2] categories. Those cover topics like use of `props.children`, context, the "container/presentational" pattern, interacting with non-React code, component lifecycle methods, Higher-Order Components, the "function-as-child / render props" pattern, and more.
There's also some more good overviews of useful React patterns at [3], [4], and [5] .
[0] https://github.com/markerikson/react-redux-links
[1] https://github.com/markerikson/react-redux-links/blob/master...
[2] https://github.com/markerikson/react-redux-links/blob/master...
[4] https://hackernoon.com/react-composition-patterns-from-the-g...
[5] https://blog.pixelingene.com/2017/09/the-common-patterns-of-...
[0] https://github.com/ReactTraining/react-router/blob/master/pa...
I was wondering what was HN's opinion on the framework. And knowing js, if I was just once more learning a soon-to-be-dead framework and I should just insist with React.
It's also the case that Vue, React, and Angular 2 are in many ways more similar than they are different, so experience with one will be helpful if you ever need to move to using another.
Finally, at some point I would advise you to take serious look into understanding webpack and babel and/or typescript and how to configure them. Webpack might be 'just' the build tool, but it is the common underpinning of pretty much all frontend development, and a lot of the complexties become a lot more managable once you understand what it is doing.
Also, Sean Larkin, one of Webpack's maintainers, has put together an online course site called "Webpack Academy" [4]. I believe the intro "Webpack Core Concepts" course is free.
[1] https://www.youtube.com/watch?v=WQue1AN93YU
[2] https://www.youtube.com/watch?v=WQue1AN93YU
[3] https://naomiajacobs.github.io/WebpackTalk/
A short explanation is: you tell Webpack which file is the "entry point" to your application. It then recursively traces all the imports from there, creates a dependency tree, and bundles all those individual files into a single output bundle. You can also configure it to transform files along the way, allowing you to compile newer JS syntax into older syntax with Babel, import images and styles into your JS bundle, and much more. It also allows you to set up code splitting so that common code shared between different bundles is extracted into a separate bundle file, and parts of your app can be dynamically loaded after the initial app starts up.
React was harder to learn, but I find myself making more components than I did in Angular and Vue. React delivers on the idea of making reusable components accessible.
[1] https://developers.google.com/web/fundamentals/web-component...
You're dissing custom frameworks at the same time as you're advocating using a custom framework. Or, as you call it, "a templating engine". Because you need much much much more than just a templating engine:
- Web Components provide a fraction of a fraction of React's capabilities. Even though React doesn't even have that many capabilities. After all, it's just the V in MVC.
- You still need data binding
- You still need state management
- You still need ways to deal with component hierarchies (good luck not forgetting to unbind all the event listeners etc.)
- You still need to re-implement your own forms [1]
- etc. etc. etc.
So what you really are proposing is: either use a framework/a bunch of helper libs (Polymer, Skate.js whatever) or end up getting crufty and unmanageable with the low-level DOM APIs that Web Components offer (there are no other APIs in the standard).
[1] There is no way to have custom elements include data in form submissions: https://github.com/w3c/webcomponents/issues/187 and the solution is "to replicate the behaviour of form elements (which requires you to also to replicate <form />)" https://github.com/w3c/webcomponents/issues/187#issuecomment...
From Wikipedia:
The UNIX philosophy is documented by Doug McIlroy in the Bell System Technical Journal from 1978:
* Make each program do one thing well. To do a new job, build afresh rather than complicate old programs by adding new "features".
* Expect the output of every program to become the input to another, as yet unknown, program. Don't clutter output with extraneous information. Avoid stringently columnar or binary input formats. Don't insist on interactive input.
* Design and build software, even operating systems, to be tried early, ideally within weeks. Don't hesitate to throw away the clumsy parts and rebuild them.
* Use tools in preference to unskilled help to lighten a programming task, even if you have to detour to build the tools and expect to throw some of them out after you've finished using them.
I'd say that the first, second, and fourth are EXACTLY what web components provide. Furthermore, things like Angular and React that include the kitchen sink are precisely the antithesis of the Unix philosophy. And lit-html does only one thing and does it well. It is not a framework.
> Web Components provide a fraction of a fraction of React's capabilities.
That's a pretty empty statement.
> You still need data binding
Which is why I suggested adding lit-html
> You still need state management
React doesn't include this either. I would suggest redux, or even something hand-rolled, considering how simple redux is. Even Dan Abramov, the creator of redux, suggests rolling your own unless you really need it.
> You still need ways to deal with component hierarchies (good luck not forgetting to unbind all the event listeners etc.)
lit-html handles this
> You still need to re-implement your own forms
See: https://www.webcomponents.org/ for countless form components.
> etc. etc.
"etc" is used when you've run out of ideas.
> There is no way to have custom elements include data in form submissions.
You would be adopting a new technology with web components. Why bother with old-school form submissions?
You are very ignorant and come off as seriously aggressive for no reason. Do your homework.
same person:
> I suggested adding lit-html > I would suggest redux, or even something hand-rolled > See: https://www.webcomponents.org/ for countless form components.
How quickly will that become crufty and unmanageable? Oh, pretty quickly.
Also, the following statement is if not false, then misleading
> I'd say that the first, second, and fourth are EXACTLY what web components provide.
- Web Components don't even do one thing well.
- There are still issues with "serving as input": you need to manually construct and add them to your templates if you need complex properties (i.e. anything that's not a string), there are issues interacting with the rest of the spec (form data, labels not supporting custom elements, input elements not being extensible, ARIA still not aligned with custom elements)
- WCs don't provide any tools and definitely do not lighten a programming task. Because at this point they provide nothing but low-level overly verbose primitives to construct custom elements. Everything else has to be brought in in the form of helpers, third-party libs or, yes, frameworks (e.g., if you call React a framework, then Polymer is also a framework).
So, original comment said this:
> I've recently tried to get into React seriously and I found myself getting stuck pretty quickly. I tried Vue.js which seem to be popular as well and I had a blast. I found the templates more intuitive, the documentation easier to read and the concepts just fun to use.
Your suggestion to go for Web Components because custom frameworks are crufty and unmanageable is disingenuous at best. You will end up with both custom frameworks on top of WebComponents and potential multiple issues that exist. Unless, of course, you go for "hundreds of components on webcomponents.org", vast majority of whom use Polymer to plug all the holes in the spec.
What you do though is twist my words every which way and fight with that twisted version. Just to point out a few things:
- I never said Web Components written in X would be incompatible with Y
- I never said Web Components were a framework
- I never said Redux was a framework
The rest I really couldn’t be bothered to lay out and dispel, as I have better things to do with my life.
I've personally worked on a large project built using over 100 in-house web components, and can tell you we've never into any issues with input. You are just picking on some minor nit you read online that has ho relevance to almost anyone.
Are you aware that a large percentage of Google's public and internal web properties are now using web components? Seems a bit absurd if input was broken.
In addition, I'd encourage you and anyone else to come by the Reactiflux chat channels on Discord [1]. They're a great place to learn, ask questions, and get help with React and related technologies.
People say this but I feel like it's disingenuous: real world experience with JSX is that you need to master a whole slew of special constraints / restrictions and exceptions before you are using it efficiently. It is effectively learning another language with about the same complexity as the template constructs in Vue.
As far as names i find vuejs more complex. I have years of experience in js. Vuje requres me throw many of those to write simple loops, if logic even onclick binds etc. For me at least reactjs is a simple framework.
<div>
{flag && flag2 && !flag3
? flag4
? <p>Blah</p>
: flag5
? <p>Meh</p>
: <p>Herp</p>
: <p>Derp</p>
}
</div>
Should be: <div>
{ flag && flag2 && !flag3
? flag4
? <p>Blah</p>
: flag5
? <p>Meh</p>
: <p>Herp</p>
: <p>Derp</p>
}
</div>this example should just be using early returns imo
added a PR: https://github.com/vasanthk/react-bits/pull/76/files
I'd bet this looks absolutely crazy to many developers:
<div *ngIf="foo; then bar else baz"></div>
An essentially eval'd code string inside a markup attribute? That uses some made-up language that's neither HTML nor JS?! I used to write plenty of code like this in various template languages, and it always felt bad.JS:
const sampleComponent = () => {
return isTrue && <p>True!</p>
};
CLJS: (defn sample-component [is-true?]
(when is-true? [:p "True!"]))
Any language that has if expressions would be preferable to JS in this case, I think. <Conditional bool={true}>
<IfTrue/>
<IfFalse/>
</Conditional>
Doesn't seem any better render() {
let foo
if (someCondition) {
foo = <ChildFoo/>
}
return (
<Bar>
{foo}
</Bar>
)
}
or: renderChildFoo() {
if (someCondition) {
return <Foo/>
}
}
render() {
return (
<Bar>
{this.renderChildFoo()}
</Bar>
)
}
or if possible, always render <Foo/> and conditionally return null in Foo's own render() method.No, it's not. It's the bastard child of XML and JavaScript. I agree that your examples are about the best you can do with JSX. But actually just JavaScript is much easier:
render() {
return Bar(someCondition && Foo())
}
or render() {
return Bar(someCondition ? Foo() : null)
}
That's not quite hyperscript but it's not far from it. <Bar>{someCondition && <Foo/>}</Bar>Just one line up in the bulleted list is: “Best approach: Move logic to sub-components“. There isn’t an example or a link because the recommendation is that simple.
Of course there are no absolutes and there are many other approaches that split difference between inline logic and additional components, but the general idea is to avoid writing a bunch of conditionals in your JSX unless you have to - and in that case, this mess of nested ternaries is one way to do it.
> If one needs such inelegant code to deal with basic boolean logic
You don't. Idiomatic React doesn't try and put complex logic in the JSX; the recommended approach (including in the linked article) is to do you logic in plain JS with small focused components or render functions.
One thing I don't like, though:
const sampleComponent = () => {
return isTrue && <p>True!</p>
};
If isTrue is 0, React will render 0. If isTrue is NaN, React will render NaN. Best to cast the conditional to boolean when using short-circuit evaluation: const sampleComponent = () => {
return !!isTrue && <p>True!</p>
};