React - Split on string not having any effect - javascript

I am trying to split a given text at each \n in order to put them on individual lines.
The problem is, in React, I am using the following code:
const details = property.details !== undefined
? property.details.split("\n").map((item, i) => {
return <p key={i}>{item}</p>;
})
: "";
but there is no splitting made whatsoever. The returned array is simply the whole string. I tried the same string in the console of the browser and it works there.
Also, the typeof property.details is string.
What am I missing?
My render function for this component is:
render() {
const property = this.state.property;
const details =
property.details !== undefined
? property.details.split(/\r?\n/).map((item, i) => {
return <p key={i}>{item}</p>;
})
: "";
return (
<Fragment>
{this.state.isLoading ? (
<div className="sweet-loading" style={{ marginTop: "120px" }}>
<BarLoader
sizeUnit={"px"}
css={override}
size={200}
color={"#123abc"}
loading={this.state.isLoading}
/>
</div>
) : (
<div className="container p-4" style={{ marginTop: "4rem" }}>
<div className="row align-items-center">
<div className="row display-inline p-3">
<h3>{property.title}</h3>
<h5 className="fontw-300">{property.zone}</h5>
<h1 className="mt-5 price-font-presentation">
{property.sale_type} -{" "}
<strong>{property.price.toLocaleString()} EUR</strong>
</h1>
</div>
<Carousel>
{property.images.map(image => (
<img key={image.id} src={image.image} />
))}
</Carousel>
<div className="row p-3">
<h3 className="border-bottom">Detalii</h3>
{details}
</div>
</div>
</div>
)}
</Fragment>
);
}
Maybe I should mention that the information is taken with a django_rest api. Maybe there is a problem with returning \n in a string from there.

It might happen because client OS uses different symbols for new lines. Try this, it's multi-platform:
const details = property.details !== undefined
? property.details.split(/\r?\n/)
: [];
EDIT:
typeof property.details is string because it's string. calling split on property.details returns array, but string remains to be string.
From your updated code sample I can see that you are basically rendering details, which results in array transforming to string back again but without line seperators.
Maybe you have to map it to paragraphs for example:
<h3 className="border-bottom">Detalii</h3>
{details.map(detail => <p>{detail}</p>)}
Also, try white-space: pre; css property as alternative

Have you tried this version:
const details = property.details !== undefined
? property.details.split('\r\n').map((item, i) =>
<p key={i}>{item}</p>;
)
: '';
(It's the extra \r)

Related

Warning on render : Received `true` for a non-boolean attribute `className`

GEtting the following error for the div.container and span.text:
Warning: Received true for a non-boolean attribute className.
If you want to write it to the DOM, pass a string instead: className="true" or className={value.toString()}.
return (
Array.isArray(contactDetails) &&
contactDetails.map((item, index) => {
return item.type === DIVIDER ? (
<div key={index}>
<Divider variant={"middle"} className={classes.divider} />
<div className={classes.dividerText}>{item.text}</div>
</div>
) : (
item.text && (
<div className={classes.container} key={index}>
<div className={classes.icon}>{item.icon}</div>
<span className={classes.text}>{item.text}</span>
</div>
)
One of your classes-props is a boolean. You cannot push a boolean (true/false) to className.
You could console.log(classes), then you will see, which prop causes the warning.
It means at least one of the className values is boolean instead of string. we can not say anything more with this piece of code.
I got the same error when i didn't give a value to className attribute like below, probably one of your variable is null or boolean etc.
<img className src={...} .../>

split function to highlight search term in React

I have some data that Im mapping through and trying to highlight the search term entered into a field. I have this little section where I pass the string value (which I verified console logs correctly) into my splitResult function. It is supposed to split that string into pieces, index them, and return the string with highlighted parts... how do I return the pieces?? Example: (the item.title should show and is not) If there is not enough code to understand this sandbox might help..
search app
//split the search term
const splitResult = (result) => {
result.split(new RegExp(`(${searchTerm})`, `gi`)).map((piece, index) => {
return <span
key={index}
style={{
background: piece.toLowerCase() === searchTerm.toLocaleLowerCase() ?
"YELLOW" : "TRANSPARENT",
}}
>
{piece} //<--is this right?//
</span>
});
};
//some of the rendering
<div key={item.index}>
<div>{splitResult(item.title)}</div>
{item.content.map((i, index) => {
return <div key={index}>{i.text}</div>;
})}
<div className={styles.searchLink}
onClick={() => {
context.setCurrentSlide(item.index);}}
>Go To This Slide {item.index}
</div>
</div>

div's background is different than it's content (same values passed)

Ok, so I have a very strange problem (I'm using next.js).
I'm mapping shuffled array.
const otherPoepleData = shuffle(allPeople).filter(item => item.full_slug !== data.full_slug).slice(0, 3)
{otherPoepleData.map((item, index) =>
<SpeakerNew data={item} key={item.id} index={index} />
)}
To sum up the problem I've put inside SpeakerNew component following code:
<div style={{ backgroundImage: `url(${image.filename})` }}>
{image.filename}
</div>
And here are the results:
<div style="background-image:
url(https://something.com/blablaba57674676343zzx.png);">
https://something.com/blablaba13123123dasdzz.png
</div>
The content of the div is 100% correct, however the backgroundImage url is incorrect. Taken from completely other person from array I'm mapping. What coulde be the problem here?

react render data array map

I have facing an issue in react js, i use array map function to render data on component but they show last value of data.
react component
if (this.state.data
&& this.state.data.length
)
{this.state.data.map(({ full_name }, i) => (
name = (
<p key={i}>{this.state.data[i].full_name }</p>
)))
}
return (
<div className="row">
{names}
</div>
show all values of data but they show last value
names data
alex
john
smith //they show last value
what should i change in my code?
anyone help me?
Try this :
const names =
this.state.data.length > 0 &&
this.state.data.map(name => <p key={name}>{name}</p>);
return (
<div className="row">
{names}
</div>
);
edited based on comment feedback below
const names = this.state.data.map((item) => (
<p key={item}>{item.full_name }</p>
))
or
const names = this.state.data.map(({full_name}) => (
<p key={full_name}>{full_name}</p>
))
here's a sandbox example
https://codesandbox.io/s/nostalgic-wood-9jrib?file=/src/App.js

How to add a <br> tag in reactjs between two strings?

I am using react. I want to add a line break <br> between strings
'No results' and 'Please try another search term.'.
I have tried 'No results.<br>Please try another search term.'
but it does not work, I need to add the <br> in the html.
Any ideas how to solve it?
render() {
let data = this.props.data;
let isLoading = this.props.isLoading;
let isDataEmpty = Object.entries(data).length === 0;
let movieList = isLoading ? <Loader /> : isDataEmpty ? 'No results. Please try another search term.' :
Object.entries(data).map((movie, index) => <MovieTile key={index} {...movie[1]} />);
return (
<div className='movieList'>{movieList}</div>
);
}
You should use JSX instead of string:
<div>No results.<br />Please try another search term.</div>
Because each jsx should have 1 wrapper I added a <div> wrapper for the string.
Here it is in your code:
render() {
let data = this.props.data;
let isLoading = this.props.isLoading;
let isDataEmpty = Object.entries(data).length === 0;
let movieList = isLoading ? <Loader /> : isDataEmpty ? <div>No results.<br />Please try another search term.</div> :
Object.entries(data).map((movie, index) => <MovieTile key={index} {...movie[1]} />);
return (
<div className='movieList'>{movieList}</div>
);
}
You can use CSS white-space to solve the problem.
React Component
render() {
message = `No results. \n Please try another search term.`;
return (
<div className='new-line'>{message}</div>
);
}
CSS
.new-line {
white-space: pre-line;
}
OUTPUT
No results.
Please try another search term.
break text to line:
render() {
...
<div>
{this.props.data.split('\n').map( (it, i) => <div key={'x'+i}>{it}</div> )}
</div>
...
Some HTML elements such as <img> and <input> use only one tag. Such tags that belong to a single-tag element aren't an opening tag nor a closing tag. Those are self-closing tags.
In JSX, one has to include the slash. So, remove <br> and try <br />
Here is how I got around this. Let message be the prop/variable that has the string containing line breaks to be displayed in HTML as follows:
message = 'No results.<br>Please try another search term.';
<div>
{message}
</div>
To make this work, we need to use \n instead of break tag <br> and set the following css on the wrapper element of this message as follows:
message = 'No results.\nPlease try another search term.';
<div className="msg-wrapper">
{message}
</div>
CSS:
.msg-wrapper {
white-space: pre-wrap;
}
OUTPUT:
No results.
Please try another search term.
If you don't want put the string inside a <div> you could use <> to do it.
Like this:
var text = <>This is a text in the first line;<br />this is a text in a second line</>;
Just split text by /n, I do this in this way:
<div>
{text.split('\n').map((item, i) => <p key={i}>{item}</p>)}
</div>
Try with span
return (
<div className='movieList'><span>{movieList}</span></div>
);
If you are like in my situation and you don't want to add css, you can do that :
render () {
...
return (
...
<Typography component="p">
...
{(contact.lastname)?<div>Hello {contact.firstname} {contact.lastname}</div>:''}
...
</Typography>
...
);
}
using ` worked for me however i am not sure if it is the exact solution to the problem :
import React from 'react';
import ReactDOM from 'react-dom';
let element = (
<div>
<h1> Hello world</h1>
This is just a sentence <br></br>
But This line should not be in the same previous line. <br></br>
The above content proves its working. <br></br>
npm v6.14.6 | react : {React.version}
</div>
);
ReactDOM.render(element,document.getElementById("html-element-id"))
You can add a span tag and add block as a class.
Pomodoro Technique Timer <span className="block">with Bla</span>
The simplest thing which I did is by creating a component.
const EmptySpace = ({ spaceCount = 0 }) => {
return (
<>
{Array.from({ length: spaceCount }, (item, index) => {
return <br key={index} />;
})}
</>
);
};
export default EmptySpace;
<EmptySpace spaceCount={1} />
In your case you could do something like this:
const msg = (
<p>
No results <EmptySpace spaceCount={2} />
Please try another search term.
</p>
);

Categories

Resources