Constructing string using react property and es6 template feature - reactjs

I need to construct the href using the react property and es6 template feature. My code is below however after rendering the subHeader in href is not replaced with its value.
subHeaders = this.props.subHeaders.map((subHeader, i) => {
return <a className="articleSidebar__summaryText" href='#${subHeader}' key={i}>{subHeader}</a>;
});
How can I achieve this?

You're not using the right syntax in the href part.
Are you trying to get an output like #something? In that case, it should be:
href={`#${subHeader}`}
You need to use template literals (``) when you want to do string interpolation. And you need to use {} around the template literal because thats the syntax you need to use in order to set a prop to some JS expression instead of some literal string.

Related

Why can't style be a plain string in React?

I know that in React JSX style attribute must be an object. But I'm wondering why it can't be a plain string like normal HTML.
JSX is compiled to normal HTML by React.createElement under the hood.
React.createElement("div", {style:"color: red;"}, "Why does this throw an error?")
Why doesn't style get added to the element like any other normal HTML attribute?
It could, but it would require some extra code.
https://egghead.io/lessons/css-style-html-with-javascript-template-strings-and-objects-in-css-in-js
I guess the first question is, if it's really worth it.

How can I use Css Modules to concatenate a class with a variable

How could I convert this className:
className={`Tooltip__message Tooltip__message--${position}`}
to a css Module className?
There are two classes, and one concatenates a variable.
You can either do this, normal JavaScript:
className={'wrapper searchDiv ' + this.state.something}
or the string template version, with backticks:
className={`wrapper searchDiv ${this.state.something}`}
Both types are of course just JavaScript, but the first pattern is the traditional kind.
Anyway, in JSX, anything enclosed in curly brackets is executed as JavaScript, so you can basically do whatever you want there. But combining JSX strings and curly brackets is a no-go for attributes.
Ref to https://stackoverflow.com/a/36209517/10789574

Are react JS attributes different from properties?

I'm reading the react JS documentation and came across this:
Specifying Attributes with JSX:
You may use quotes to specify string literals as attributes:
const element = <div tabIndex="0"></div>;
I'm fairly comfortable with javascript but I'm not quite sure what the documentation means by "attributes". I know about object properties but this looks like a simple variable.
What exactly is a react js attribute if it is different from a property?
html elements have both attributes and properties
there are a few different scenarios for how they relate to each other. There doesn't necessarily have to be both an attribute or property for each value set on an element.
1. attributes
attributes can be set in html
<a id="mylink" href=""/>
where href is an attribute
or attributes can be set by using the set attribute method of an element
document.getElementById("mylink").setAttribute("href", "")
and read using
document.getElementById("mylink").getAttribute("href")
2. properties
properties can be set and read by retrieving the element as well
document.getElementById("mylink").href = ""
where href is a property
when they are set the first way, you are setting the attribute, the second sets the property.
Usually the underlying element attribute and property are
automatically synchronized, sometimes they are not.
Sometimes there is no matching attribute or property,
only one or the other exists.
Attributes and properties are part of native html elements, which React provides additional support and abstractions around.
Custom React components (such as <MyComponent prop=""/> or <MyComponent prop={someVar}/>), which you create yourself, accept props using the same syntax. The word props in this context refers purely to React props. React custom component props are just plain javascript values passed into your component. These custom components don't get added to the page. They are used to organize and render actual html elements.
When mounting a native component inside of a custom component (such as <div id=""/> or <div id={someVar}/>), the React library sets the underlying html attribute on the native browser element.
So there are two things to keep in mind here
html element attributes verse html element properties.
custom element props are neither of those, but setting a prop on a JSX
native element such as a div, set's the generated element's
attribute.
Now that's been established, the documentation above is saying: if you want to set an attribute value to a string you can use that specific syntax. That syntax only works for setting attribute values to strings.
You can use either:
<div id="myid"/>
or
<div id={'myid'} />
to set a string attribute value. They're probably just pointing out the syntax differences.
if you do:
<div tabIndex="0"/>
the value of tabIndex is the string 0 not the number zero
verses this:
<div tabIndex={0} />
which will pass the number zero to the tabindex attribute of the underlying html element
To me if we pass any parameter in function component then what we diclare in html is properties.But if you use (className/style/etc...) directecly in html then it will be attributes.

Appending a prop to an already existing attribute inline

Is there a way to append a property from this.props to an HTML element's attribute that already exists, and to do it inline (in the name of code-simplicity), without any variables/addons?
Something like this (but obviously this one and few other ways that I tried to append didn't work for me):
render() {
return (
<div className="entity" id="ent"+{this.props.index}>bla</div>
);
}
I do know that I could declare a variable before, append the prop to it and then use it as the attribute, but I have many lines like this and it will make my code bigger than I wanted it to be.
Thanks.
You can concatenate attributes as you usually do with strings:
<div className="entity" id={"ent" + this.props.index}>bla</div>
or (es6 syntax)
<div className="entity" id={`ent${this.props.index}`}>bla</div>
id={"ent" + this.props.index}
Or using interpolation instead of string concatenation.
id={`ent${this.props.index}`}

ng-class doesn't do what a simple css class does

I was expecting ng-class to at least do what a simple class does i.e. apply a css property. In the plunker example, if the replace ng-class with class, it works and I get the indent.
i.e. ng-class="indentLeft" doesn't work but class="indentLeft" does. What am I missing ?
See a simple plunker here: http://plnkr.co/edit/moLu0BmgEYVm3xFQDcw8?p=preview
ngClass requires an expression to evaluate.
ng-class="{'indentLeft' : (item == true)}"
The json structure is property name in '' is the class you want to apply and that property value detracted if it should be applied via true/false
String Expression
When you do this, ng-class="indentLeft" angularjs doesn't know that it is a string and most likely is trying to evaluate it from the scope.
If you wrap the property in '' and make it a string literal the plunker should work correctly
ng-class="\'indentLeft\'"
Updated plnkr

Resources