The docs say that a JSX attributes with strings are the same as attributes with braces...
<Thing attr='val' /> === <Thing attr={'val'} />
I thought I read something that said only use braces when needed because strings are more performant, but I can't find the reference now. Is there an evaluation cost for braces?
No there is no performance difference. Look at the code that's generated by each style:
<div first="abc" second={"def"}/>
// Compiles to:
React.createElement("div", { first: "abc", second: "def" });
Nicer to avoid unneeded braces though.
JSX is actually parsing it to a JS object anyway, so it's either string creation overhead for the parser or string creation overhead in your component. It's trivial either way. With a string literal, though, it's just visually noisy in the code. It only really serves a purpose if the val is a variable or expression.
There is, however, a perfomance hit in a templating engine, such as that employed by the new interpolated strings. E.g.:
`It is a ${'cat'}`
would be slower than:
`It is a dog`
which should be slower still than just a plain literal:
'It is a dog'
I'll leave it as an exercise for the reader to find the interpolation part in the JSX engine. ;) https://github.com/jsx/JSX/tree/master/src
Is there an evaluation cost for braces
Yes, As you can see anything inside {} will be considered as javascript code, so that will be executed , if you just want to assign the string then
just simply use the attr='val' rather than attr={'val'}
but if you have assignment condition based then you can use attr={'val'}
like
attr={ (condition) ? 'val1' : 'val2'}
I Hope , this will clear your thoughts.
For more details :
https://reactjs.org/docs/jsx-in-depth.html
Here you can read behind the scenes of string interpolation and speed performance :
https://koukia.ca/string-interpolation-vs-string-format-string-concat-and-string-builder-performance-benchmarks-c1dad38032a
Related
I am working on a project that uses Katex format to display mathematical formulas.
Now I am facing a bit of a problem here.
For rendering a fraction the katex syntax is
\dfrac{x}{y}
Now if I have a variable x of value 3 and another variable y of value 5.
How would I inject the values into the Katex syntax?
I want to have something like
var x = 3;
var y = 5;
\dfrac{x}{y}
where the x and y in katex syntax will be replaced by the actual values.
Note: I am also using the https://github.com/talyssonoc/react-katex
to render Katex.
I think I'd use macro substitution for this. Try to get your formula expressed as \frac{\x}{\y} by whatever machinery is generating the formula. Then you can substitute either the variable names or the values in place of those macros. Something like this:
katex.render("\\frac{\\x}{\\y}", element, {
macros: {
"\\x": String(x),
"\\y": String(y),
}
});
If you don't have a way to control how the formulas are constructed initially, this merely shifts the problem from substituting values into the formula to substituting commands into it. In that case, you probably want to tokenize the input string into commands \… and other letters. Commands remain as they are, while other letters are subject to variable substitution.
One thing to be careful of is grouping: Input \frac xy renders just fine, but with x=34.5 and y=5.67 substituted in the naive way, the result \frac 34.55.67 (which is what both text and macro substitution will give you) renders as \frac{3}{4}.55.67. So make sure that each macro you have in your formula is enclosed by {…} or add another level of {…} when you do the substitution as in "\\x": "{" + x + "}". Enclosing macros by {…} inside the formula has the benefit that you won't have to worry about a macro eating a subsequent space: \text{\x is 2} is bad but \text{{\x} is 2} is better.
But even with grouping done correctly, this approach is not perfect since not all non-commands are indeed variables. For example with \begin{array}{rlrl}…\end{array} neither the a in array nor the r in rlrl should be considered a variable. Fixing this is really problematic, as it requires a lot of semantic insight.
One way to tackle this dilemma would be letting KaTeX do its rendering and then doing the substitution in the resulting DOM subtree. You should be able to identify variables as <span class="mord …">…</span> (mord stands for math ordinary). This means you depend on the exact representation KaTeX uses for its output, so you should make sure you run a fixed version of KaTeX as these internal things are subject to change without notice. Also be aware of the fact that in some (possibly future) version this might break certain constructs which depend on the width of a given box, although even things as problematic as \underbrace appear to work with this substitution approach at the moment.
All of these work of course, but which one is the best practice for ES6 in a jsx file? (ignoring the formatting). It is my understanding that template strings are meant mostly (solely?) for descriptive console logging and not for regular usage?
<div className={`dropdown-menu dropdown-menu-media`}/>
<div className={"dropdown-menu dropdown-menu-media"}/>
<div className={'dropdown-menu dropdown-menu-media'}/>
I realize there is no functional difference between single and double quotes (unless you are alternating between the two to avoid escaping)... but... is one or the other more common or is it "completely" a matter of 'taste' ? i.e. if you were going through code and saw single and double quotes randomly changing for the same case / usage, and you had to make it uniform, which would you use?
const inputProps = {
onChange: this.onChange,
className: 'form-control',
id: "someId",
status: 'active',
isOpen: "open"
};
When working with JSX best practice is to use double quotes directly (no-braces) if just a simple string, or use backtick if interpolating a var into the string
JSX attempts to mimics HTML attributes making it more accessible when learning for first time, and beyond that I find it provides a clear visual distinction between JSX attributes and ordinary strings when scanning code, as they are likely syntax highlighted the same colour
In more general usage...
Backticks are ES6 introduction for template literals and should really only be used for that UNLESS you want to do a multiline string
There is no difference whatsoever between the single and double quotes, however in my experience there has been for a long time a move towards using single quotes (supported by linters) simply because it makes for less cluttered readable code
Sticking to a single code style across projects and enforcing via linting is also a good idea because it reduces escaping mistakes
It often depends on the other languages you have used as some languages allow interpolation in one or the other or in Java for example single quotes denote char rather than String
For what its worth here's my preference for the above reasons...
const awardWinningActor = 'Nic Cage'
const oscarNight = `And the award for Best Actor goes to ${awardWinningActor}`
const winnersSpeech = `Some really long but also totally awesome amazing speech
and also possibly some screaming and a leather jacket slung into the crowd`
<NicCage oscarFor="Best Actor" says={`Here's my ${winnersSpeech}`}} />
None of them.
<div className="dropdown-menu dropdown-menu-media"/>
Double quote string literals when they are JSX attributes. Don't wrap in expression {} blocks.
For dynamic classnames, use the classnames package, not string concatenation.
<div className={
classNames('dropdown-menu dropdown-menu-media', this.props.className)
}/>
Single or double quotes are equivalent, there is not difference between the two, they serve a use case when you want a word in string to have double quotes then you can wrap the entire string in single quotes or vice versa. However backtics are generally used when you want to resolve a variable along with the string
For example
const inputProps = {
onChange: this.onChange,
className: 'form-control',
};
<div className={`dropdown-menu dropdown-menu-media ${inputProps.className}`}/>
For Example,
We could just use
onClick={(foo)}
or something else.. instead of
onClick={this.foo.bind(this)}
Just curious if there is any particular technical constraint.
Let me answer the question from a design/philosophical perspective, instead of a technical one (the other answers do that pretty well already).
React COULD have, there would be no problem to that. But why have multiple ways to do things when you can have one (React tries to stay as close to ES standards as possible). If there are multiple ways to do a single task, it'll affect readability across codebases, making it harder for developers to ease into a codebase since they would have to unravel layers upon layers of abstraction till they gets to the core idea.
Basically, I think it was a design choice to NOT add a lot of the syntactic sugar that could have been added (JSX itself is already a form of syntactic sugar, we don't need syntactic sugar on our syntactic sugar).
From the React Docs:
"In general we resist adding features that can be implemented in userland. We don't want to bloat your apps with useless library code. However, there are exceptions to this."
"We prefer boring code to clever code. Code is disposable and often changes. So it is important that it doesn't introduce new internal abstractions unless absolutely necessary."
Source: https://facebook.github.io/react/contributing/design-principles.html
Representing the ideas from this talk: https://www.youtube.com/watch?v=4anAwXYqLG8
onClick={foo} is something completely different to onClick={this.foo.bind(this)}, and parentheses are required for maths.
.bind causes a new function to be created on every single invocation, so this would not be very performant.
(I assume) an aim of JSX to try and be as close to regular JS as possible so it's easy to pick up.
It is not the realm of JSX to add new language elements; a bind operator is most definitely a new language element.
If you notice, JSX doesn't provide any new language constructs other than what is necessary to call React.createElement. Additionally, you probably wouldn't want to use .bind like this anyway due to fact it's creating a new function every time. Finally, the parens are required for mathematical operations - you couldn't use {()} because what if I wanted to use a mathematical operation like {(a + b) * c}? Any interpolation that JSX does must be a JavaScript expression, currently, so unless JavaScript itself supports this syntax it's unlikely the interpolation will too.
You may be interested in the function bind operator, but I'd recommend you avoid using bind in this manner; instead, bind the functions once in the component constructor, like so:
class MyComponent extends Component {
constructor() {
this.boundOnClick = this.onClick.bind(this)
}
render() {
return <button onClick={this.boundOnClick}>Foo</button>
}
}
// with function bind operator
class MyComponent extends Component {
constructor() {
this.boundOnClick = ::this.onClick
}
render() {
return <button onClick={this.boundOnClick}>Foo</button>
}
}
This ensures you only create the bound function once. For stateless components, you don't have access to this anyway so there's no need to use bind.
If JSX were to introduce an alternative syntax to this, I personally would be opposed to it, though if they could overcome the limitations I've mentioned above, there's nothing technically stopping them.
It is more a problem with ES6 which does not have automatic binding of "this" to class methods. In ES7, there is a proposal to introduce a new operator ::. With ES7, you could write:
onClick={this::foo}
Trying to implement something like this:
arr = (1..10)
arr[2,5] = [2,3,4,5]
arr(2,5] = [3,4,5]
arr[2,5) = [2,3,4]
arr(2,5) = [3,4]
Well, we need to override four bracket opreators: [], [), (], ()
Any ideas?
It's called "Including or excluding" in mathematics. https://en.wikipedia.org/wiki/Interval_(mathematics)#Including_or_excluding_endpoints
In short, this is not possible with the current Ruby parser.
The slightly longer answer: You'd have to start by modifying parse.y to support the syntax you propose and recompile Ruby. This is of course not a terrible practical approach, since you'd have to do that again for every new Ruby version. The saner approach would be to start a discussion on ruby-core to see if there is sufficient interest for this to be made part of the language (probably not tbh).
Your wanted syntax is not valid for the Ruby parser, but it could be implemented in Ruby with the help of self-modifying code.
The source files need to be pre-processed. A simple regular expression can substitute your interval expressions with ordinary method syntax, i.e.
arr[2,5] -> interval_closed(arr,2,5)
arr(2,5] -> interval_left_open(arr,2,5)
arr[2,5) -> interval_right_open(arr,2,5)
arr(2,5) -> interval_open(arr,2,5)
The string holding the modified source can be evaluated and becomes part of the application just like a source file on the hard disk. (See instance_eval)
The usage of self-modifying code should be well justified.
Is the added value worth the effort and the complications?
Does the code have to be readable for other programmers?
Is the preprocessing practical? E.g. will this syntax occur in one or a few isolated files, or be spread everywhere?
Just wondering if there is a recommended solution for the following scenario.
I have a complex expression in my markup to show some error message, e.g.
ng-show="currentSection == 'pickup-from' && carHireEnquiryForm.pickUpLocation.$dirty && carHireEnquiryForm.pickUpLocation.$invalid && carHireEnquiryForm.pickUpLocation.$error.isLocation"
This can make the markup messy and hard to unit test, so to get around this I created a function for this, e.g.
ng-show="isShowError()"
Now the isShowError can easily be tested. Problem now is that the isShowError is invoked on every digest even if the element is not visible. This for me is even worst as performance it very important.
Is there a better way to achieve this? Is expressions the recommend way to do this? What if the expression had to include 20 statements? I am keen to reduce the amount of business logic in my markup as well.
Thanks in advance
There is not much of a difference between using function and expression, considering the fact that the function is also evaluated like an expression.
Implies if you are just using an expression, that too is being evaluated on every digest cycle. The function just add lightweight indirection.
As long as the expression evaluation is fast you can use either, but functions are better as they can encapsulate the validation logic.
The problem comes when we knowingly or unknowingly add some time consuming operation to the function, slowing down the function evaluation.