how to store jsx element to javascript variable - javascript

I want to reuse my jsx element in multiple places.
const value= <div>some text<Link href="abc.com">text</Link></div>
and I want to call value in multiple places.
I tried adding ' ' for the div but not getting element properly. It is returing as string. Can someone explain me the correct syntax to render jsx element to JavaScript variable?

I want to reuse my jsx element in multiple places.
You can't. It can only be used in one place. It would appear that you can, I stand corrected by Mosè Raguzzini, this works just fine::
const value= <div>some text<Link href="http://example.com">text</Link></div>;
ReactDOM.render(
<div>
{value}
{value}
{value}
</div>,
document.getElementById("root")
);
Live Example:
const value= <div>some texttext</div>;
ReactDOM.render(
<div>
{value}
{value}
{value}
</div>,
document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>
Another approach is to have a function that creates identical copies of it:
const getValue = () => <div>some text<Link href="abc.com">text</Link></div>;
Then when you want one, use getValue() to get it.
Or even give that a capital letter so it's a functional component:
const Value = () => <div>some text<Link href="abc.com">text</Link></div>;
Live Example (of both):
const getValue = () => <div>some texttext</div>;
const Value = () => <div>some texttext</div>;
ReactDOM.render(
<div>
{getValue()}
{getValue()}
<Value />
<Value />
</div>,
document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>
how to store jsx element to javascript variable
You can't reuse a React element the way you've shown, but there's nothing wrong with:
const value= <div>some text<Link href="abc.com">text</Link></div>
(other than relying on ASI at the end, because there's no ;). That works just fine. But it doesn't make it reusable.
Here's an example doing that:
const value= <div>some texttext</div>;
ReactDOM.render(
<div>
{value}
</div>,
document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>

You could create a stateless component to reuse said component:
import React from "react"
export const MyComponent = () => (
<div>
some text <Link href="abc.com">text</Link>
</div>
);

Related

how to add html tags inside jsx (ReactJS)

I'm trying to put a html tag inside a span to give some styling to a certain word. but it results in a plain text instead.
expectation:
abc AND xyz
what I get instead:
abc <strong>AND</strong> xyz
here's my code: ( codesandbox )
import { useState } from "react";
export default function App() {
const [isLoading, setIsLoading] = useState(false);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<div>
<span>{isLoading ? "abc" : `abc <strong>AND</strong> xyz`}</span>
</div>
</div>
);
}
You can just add it like this
<span>{isLoading ? "abc" : (<>abc <strong>AND</strong> xyz</>)}</span>
One issue with your approach is that there are multiple adjacent DOM nodes. You can wrap them using a fragment:
<>abc <strong>AND</strong> xyz</>

How to get React to parse new lines from components? [duplicate]

I have the following React code:
render() {
const str = 'Line 1. **new-line** Line 2.';
return (
<p> {str} </p>
);
}
I would like the output to be:
Line 1.
Line 2.
That is - to add a new line between the words.
I have tried \n but it does not work.
How could this be accomplished?
Edit: The string is received from a server.
Set CSS-Style for the paragraph as below, it will break line on \n and wrap text according to parent width.
white-space: pre-wrap;
or
white-space: pre-line;
A more traditional approach is to just create an array with your strings, with a <br /> tag in between. Arrays are, as of React v16 a valid return value for Elements.
class App extends React.Component {
render() {
const arr = ['Line 1. ', <br />, 'Line 2.'];
return (
<p> {arr} </p>
);
}
}
ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
If you are getting a string from some API, you could create such an array by finding all <br /> substrings and replace them with actual JSX <br />'s. The following code will take your string and do a string split on every instance of <br />. This will give you ['Line 1. ', '', 'Line 2.']. As you can see, every odd element in the array is where we want to push a JSX <br />. We can do that quite simply in a loop.
class App extends React.Component {
render() {
const str = 'Line 1. <br /> Line 2.';
const arr = str.split(/<br \/>/);
const resultArr = [];
arr.forEach((item, i) => {
if(i%2===0) resultArr.push(<br />);
resultArr.push(item);
});
return (
<p> {resultArr} </p>
);
}
}
ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
The other approach is to either use dangeourslySetInnerHTML() or use template literals.
You could use template literals for that along with the css rule white-space: pre to preserve newlines. See my demo below:
class App extends React.Component {
render() {
const str = `Line 1.
Line 2.`;
return (
<p style={{whiteSpace: 'pre'}}> {str} </p>
);
}
}
ReactDOM.render(<App />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
style={{ whiteSpace: 'break-spaces' }}
For that purpose you have to use something called dangerouslySetInnerHTML.
Example
render() {
const str = 'Line 1. <br /> Line 2.';
return (
<p dangerouslySetInnerHTML={{ __html: str }}/>
);
}
You could accomplish this by using CSS instead.
p {
white-space: pre;
}
You render then becomes:
const str = "Line 1.\nLine 2."
return (<p>{str}</p>)
This is what I do.
<span>{<br/>}</span>
Using CSS - (Simply add it to content's div. Wraps and adds new-line for every '\n' appended to content)
p {
white-space: pre-wrap;
}
Use React's dangerouslySetInnerHTML - (Apply to parents div and parse any tags in the value field. Works similar to innerHTML.)
<div dangerouslySetInnerHTML={{__html: '<p>First · Second</p>'}}></div>
Link for more information about dangerouslySetInnerHTML:
[https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml][1]
You can easily achieve it by doing the following:
myTextHere={<span>Hello<br />Hi</span>}
Output will be like this:
Hello
Hi

Add <br> tag using replaceAll() in javascript

I have this string:
export default function App() {
const string = 'test data,cars,colors,demo';
return (
<div className="App">
<h1>Hello {string.replaceAll(',','<br>')}</h1>
</div>
);
}
I expect:
test data<br>cars<br>colors<br>demo
But i get one string without breack inside my string. How to achieve what i expect using replaceAll()?
In order to display html from string you have to use dangerouslySetInnerHTML
export default function App() {
const string = 'test data,cars,colors,demo';
return (
<div className="App">
<h1 dangerouslySetInnerHTML={{ __html: `Hello ${string.replaceAll(',','<br>')}`}}></h1>
</div>
);
}
Assuming this is a React application you need to use dangerouslySetInnerHTML to add the new HTML to the page.
function Example() {
const string = 'test data,cars,colors,demo';
const html = `Hello ${string.replaceAll(',', '<br>')}</h1>`;
return (
<div className="App">
<h1 dangerouslySetInnerHTML={{ __html: html }} />
</div>
);
}
// Render it
ReactDOM.render(
<Example />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
I don't suggest you dangerouslySetInnerHTML. It introduces both security and performance issues, and even if you are working on learning project, you better avoid such an approach.
The reason why your code does not work, JSX does not magically convert string "<br>" into appropriate element (until there is dangerouslySetInnerHTML, sure).
But JSX can render arrays just fine. It allows us to split initial string into elements: string.split(', ') and then inject JSX's <br /> with the help of .flatMap()(think about it as if .join() could return array with additional elements in between elements of source array).
{
string.
split(', ').
flatMap((el, index) => index ? [<br />, el]: el)
}
This approach is way more powerful than dangerouslySetInnerHTML since instead of simple BR you may use any JSX tree with React custom components, context and event handlers.
Another approach is to replace ', ' with newlines and apply CSS style white-space: pre-wrap(check white-space docs on all values available)

Adjacent JSX elements must be wrapped in an enclosing tag while adding bootstrap to my react code

Line 15:1: Parsing error: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?
13 | //crossorigin></script>
14 |
> 15 | <script>var Alert = ReactBootstrap.Alert;</script>
| ^
Somewhere in your code you're doing:
const Example = () => (
<div />
<div />
)
You cannot do that. React can only returns one parent element. So you have to wrap it with another div:
const Example = () => (
<div>
<div />
<div />
</div>
)
However, this will bloat your markup with another div which is just to satisfy React. So you can use React.Fragment so that your markup doesn't have an unnecessary div like:
const Example = () => (
<React.Fragment>
<div />
<div />
</React.Fragment>
)
Or in short, you can write it as:
const Example = () => (
<>
<div />
<div />
</>
)

Passing a number to a component

I am trying to pass a number to a React component but it is getting parsed as string (jsfiddle). How do I make React understand that I am passing a number? Should I cast the string to a number in the component?
var Rectangle = React.createClass({
render: function() {
return <div>
<div>{this.props.intValue + 10}</div>
<div>{this.props.stringValue + 10}</div>
</div>;
}
});
React.render(<Rectangle intValue="10" stringValue="Hello" />
, document.getElementById('container'));
<script src="https://facebook.github.io/react/js/jsfiddle-integration.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
It seems that in case of integers (and actually for strings as well) I should be passing the numbers via {} like so:
React.render(<Rectangle intValue={10} stringValue={"Hello"} />, document.getElementById('container'));
You can either use:
<MyComponent param1={10} param2={20} />
Or:
<MyComponent {...{param1: 10, param2: 20}} />

Categories