Rendering a Constant Inside of a React Class Component - reactjs

I have a quick question regarding the way to render content using constants in a React class component. So the following code works fine (rendering a constant using the map function):
class App extends React.Component {
array = [
{
name: "Sarah",
age: 27
},
{
name: "Sam",
age: 35
}
]
render() {
const output = this.array.map(elem => (
<div>
<p>{elem.name}</p>
<p>{elem.age}</p>
</div>
));
return (
<div>{output}</div>
);
}
}
However, the following produces a blank page (I am simply defining a constant that returns a div and trying to render it):
class App extends React.Component {
render() {
const Output = () => (
<div>Hello</div>
);
return (
<div>{Output}</div>
);
}
}
But virtually identical code works if instead of the curly braces I use the angular ones:
class App extends React.Component {
render() {
const Output = () => (
<div>Hello</div>
)
return (
<div>
<Output />
</div>
)
}
}
So it seems like this has something to do this curly and angular brackets. Curly braces work when I use a map function but do not when I define a constant that returns a div inside a render method and try to render it directly. Then it works again when I use angular brackets... This is kind of strange. I understand that this is far from the most important thing, I'm just trying to get to the bottom of this. Thank you in advance!

Angular brackets are used to render components. Since you've defined Output as a function which returns some JSX, this makes it a function component as far as React is concerned (or rather Babel, which handles the transpilation of your JSX).
You can use curly brackets but then you should change Output to a React node. Here's how you'd do that:
class App extends React.Component {
render() {
const Output = <div>Hello</div>
return (
<div>{Output}</div>
);
}
}
Check THIS answer for some clarification regarding the difference between React nodes, elements etc.

class App extends React.Component {
render() {
const Output = () => (
<div>Hello</div>
);
return (
<div>{Output()}</div>
);
}
}
if you try to call a function Output() it will return the JSX but follow this article they dont recommend that

Related

wrap symbol of `{}` around react render

class App extends React.Component {
renderSomething = () => `something`
render() {
return <div>{` `{` ${this.renderSomething()} `}` `}</div>
}
}
https://codesandbox.io/s/6yomj6wj73
I want to output {something} on the screen without modify renderSomething function, any clue why above code failed?
Create a template string which surrounds your content in braces, then use that in the JSX. I split up the steps into multiple variables which should hopefully make things clearer.
class App extends React.Component {
renderSomething = () => `something`
render() {
const innerText = this.renderSomething()
const wrappedWithBraces = `{${innerText}}`
return <div>{ wrappedWithBraces }</div>
// in short: <div>{ `{${this.renderSomething()}}` }</div>
// but I prefer the non-short version, since it's much more readable :)
}
}

store a javascript value to less variables + reactjs

I am trying to fill less variable value with a js variable from an html page in reactjs based app.
index.html
<script>window.baseColor = '#000000'//Color value will be dynamic</script>
style.less
#baseColor: window.baseColor
I don't think this is possible but you can do it using inline style and if you are going to use it in multiple components you can use the new context API
const BaseColorContext = React.createContext('#000000')
class ColorProvider extends React.Component {
state = {baseColor: '#fff'}
render() {
return (
<BaseColorContext.Provider value={this.state.baseColor}>
{this.props.children}
</BaseColorContext.Provider>
)
}
}
class App extends React.Component {
render() {
return (
<ColorProvider>
<BaseColorContext.Consumer>
{val => <div style={{backgroundColor:val}}>content here</div>}
</BaseColorContext.Consumer>
</ColorProvider>
)
}
}

Can I add two proptypes together after they are rendered? If so, how can I accomplish that?

()I have a div with a prop that I would like to display based on whether a prop is bigger in number than another prop. I have a lot going on in this particular component and I'm concerned that all of the following things I'm trying to do are not possible.
this.props.currentValue < this.props.newValue is not working for me, but everything else is working just fine.
I'm very new to React. Any help would be awesome!
Oh, and the value of currentValue and newValue are inside of the rates component on a separate page.
import React, {PropTypes, Component} from 'react';
import Header from '../compare-table-header/compare-table-header';
import './compare-table-row.css';
export class Rates extends Component {
constructor(props) {
super(props);
this.displayThing = this.displayThing.bind(this);
}
displayThing() {
const increase = <div>{this.props.details}</div>;
const thing = <div>hi</div>;
if (this.props.currentValue < this.props.newValue) {
return increase;
} else {
return thing;
}
}
render() {
const {currentValue, newValue} = this.props;
return (
<div>
<Header heading="Rates" />
<div className="value-heading">{currentValue}</div>
<div className="value-heading">{newValue}</div>
</div>
<div>{this.displayThing()}</div>
</div>
</div>
</div>
);
}
}
Rates.propTypes = {
currentValue: PropTypes.number,
newValue: PropTypes.number
};
The line with this.displayThing isn't rendering anything because you're passing a reference to the function itself, instead of calling the function and rendering the value it returns.
That line should do what you expect if you change this.displayThing to this.displayThing().
But you also have some mismatched tags. The Header component is opened and closed on the same line. From your indentation, it looks like you meant for the lines below it to be rendered as children of the Header component, but that's not what's actually happening.
You could clean that up like this:
return (
<div>
<Header heading="Rates">
<div className="value-heading">{currentValue}</div>
<div className="value-heading">{newValue}</div>
</Header>
<div>{this.displayThing()}</div>
</div>
);
Or, if your Header component doesn't render any children, that might look like this:
return (
<div>
<Header heading="Rates" />
<div className="value-heading">{currentValue}</div>
<div className="value-heading">{newValue}</div>
<div>{this.displayThing()}</div>
</div>
);
If you want to go a little further, you can also remove some code and simplify the class a little by defining the displayThing function as an arrow function:
Instead of this:
export class Rates extends Component {
constructor(props) {
super(props);
this.displayThing = this.displayThing.bind(this);
}
displayThing() {
const increase = <div>{this.props.details}</div>;
const thing = <div>hi</div>;
if (this.props.currentValue < this.props.newValue) {
return increase;
} else {
return thing;
}
}
// ... rest of the class
}
you can make displayThing into an arrow function and get rid of the constructor, like this:
export class Rates extends Component {
displayThing = () => {
const increase = <div>{this.props.details}</div>;
const thing = <div>hi</div>;
if (this.props.currentValue < this.props.newValue) {
return increase;
} else {
return thing;
}
}
// ... rest of the class
}
The class works the same either way, but it saves a few lines of code.

React map redux state to create multiple components within a component

I am using the react-redux-mapbox-gl library. I have an array of spots that I want to map in order to create multiple overlay components within the Mapbox Component. However on trying to map the array I always get an undefined error. I am new to React/Redux so am not sure what the issue is.
My Component Below:
import React from 'react';
import Mapbox from 'react-redux-mapbox-gl';
import SpotsOverlay from './SpotsOverlay'
const mapStateToProps = state => ({
spots: state.homemap.spots
})
class HomeMap extends React.Component {
render(){
return (
<Mapbox
mapboxgl={mapboxgl}
accessToken={mapAccessToken}
getMap={this.getMap}
style={this.mapStyle}
options={this.mapOptions}
>
{
this.props.spots.map(spot =>{
return (
<SpotsOverlay
overlay={this.overlay}
key={spot.id}/>
);
})
}
</Mapbox>
);
}
}
Do the mapping outside of the return method might help.
class HomeMap extends React.Component {
render(){
let spots = [];
if(this.props.spots) {
spots = this.props.spots.map(spot =>{
return (
<SpotsOverlay
overlay={this.overlay}
key={spot.id}/>
);
});
}
return (
<Mapbox
mapboxgl={mapboxgl}
accessToken={mapAccessToken}
getMap={this.getMap}
style={this.mapStyle}
options={this.mapOptions}
>
{spots}
</Mapbox>
);
}
}
As #MayankShukla said in his comment, the reason why this works better is that
initially reducer state is {}, so state.homemap.spots will be undefined and when you were using map of undefined

Which react declaration to use

I am new to react and seen following declaration in few tutorials.
I am confuse on which to use. Is there any guideline on which to prefer under difference situation?
Declaration 1
const elem = function() {
return <div>Hello World!</div>
}
Declaration 2
const elem2 = <div>Hello World!</div>
Declaration 3
class App extends Component {
render() {
return (
<div>Hello World!</div>
);
}
}
Considering
class App extends Component {
render() {
return (
<div>Hello World!</div>
);
}
}
is a React component and hence should be used when you wish to create separate Components for different functionalities for you Application which includes states and props being passed.
As per
const elem2 = <div>Hello World!</div>
it should be used when the JSX elements do not contain extra logic and contian static contents
const elem = function() {
return <div>Hello World!</div>
}
should ideally be used when you want to perform certain modification on the data and return the JSX element, also if you wish to perform some conditional returns and stateless retuns
You can always use functional components when the component is composed only from the render function.
That means, if your component has the following form:
class MyComponent extends React.Component {
render() {
... do something ...
}
}
then you can replace it with
const MyComponent = (props, context) => {
... do something ...
}
Functional components cannot have state (they are stateless) and you cannot access the component lifecycle (e.g. componentDidMount). You also cannot use pure rendering with them because you cannot override shouldComponentUpdate.
They are the purest form of a component, they convert properties into UI and have no other side-effects.
I would recommend to use them as much as possible because they enforce a good programming style (especially with redux architecture) but you won't be able to use them everytime. The "smarter" a component is, the less possible it will be to use a functional component (see Smart vs Dumb components).
They are especially useful when defining Higher Order Components.
Also note that you can often combine all approaches, consider
render() {
const renderContents = () => {
return (
<div className="contents">
this.props.children
</div>
);
}
return (
<div>
{renderContents}
</div>
);
}
You can define a "component" inside other component's render. As you can see, there is no difference between a function and a functional component. And the same applies for constants. Defining a constant <div /> is not different from defining a constant string or a number. You don't need to wrap it into a component/function. You can also do things like this:
const contents = (() => {
if (props.children.count === 0) {
return null;
}
return (
<div>{props.children}</div>
);
})();
This is an immediately invoked function.

Resources