You must pass a valid ReactElement | Sweetalert-react - javascript

I am trying to use the sweetalert-react package (https://github.com/chentsulin/sweetalert-react) as a modal for my app.
Right now I got it to work, but I want to be able to display a const that has my component:
const clusterDoors = lock.doors.map(clusterDoor => {
return (
<div key={clusterDoor.port_id}>
<ClusterListItem
clusterDoor={clusterDoor}
customer={
clusterDoor.allocation.customer ? (
keyedCustomers[clusterDoor.allocation.customer]
) : (
false
)
}
.....
So I read their docs and found out that I can achieve that with ReactDOMServer.renderToStaticMarkup. So I simple need to:
text={renderToStaticMarkup(<MyComponent />)}
But the problem is that my component is inside of a constant, so if I try to do:
text={renderToStaticMarkup({clusterDoors})}
I will get the error:
You must pass a valid ReactElement.
I wonder if there's some workaround to this?
I did some research and tried also tried to do:
const clusterDoors = React.createClass({
render: function() {
lock.doors.map(clusterDoor => {
return (
<div key={clusterDoor.port_id}>
<ClusterListItem
clusterDoor={clusterDoor}
customer={
clusterDoor.allocation.customer ? (
keyedCustomers[clusterDoor.allocation.customer]
) : (
false
)
}
delivery={
clusterDoor.allocation.delivery ? (
keyedDeliveries[clusterDoor.allocation.delivery]
) : (
false
)
}
/>
</div>
)
})
}
})
But that didn't do the trick.
If I pass it a valid react component (ClusterListItem) my app won't break, but nothing will show because of the array clusterDoor wont exist.
I hope I explained my situation well. Thanks for reading.

The problem with your code is that you are passing an array of elements because clusterDoors is an array and renderToStaticMarkup is expecting a single element. Therefore you are getting this error.
Solution: Just wrap your array in a div tag so it becomes a single node element like this
text={renderToStaticMarkup(<div>{clusterDoors}</div>)}

Related

JavaScript $ReadOnlyArray<CompositeDecorator>

I'm trying to get some code working which will highlight links automatically in an rich text editor. This is not my own written code this is from draft js and is provided by many different web pages because this is the absolutlly basic how it should work out.
My major problem is that when I deifinine the linkDecorator of the type CompositeDecorator the compiler tells me that the linkDecorator is $ReadOnlyArray which can't handle the provided input. I have absolutly no idea what I'm doing wrong because for people on about 10 different websites exactly this code works out well. Even in an online compiler were you can compile the code yourself it works.
Also practically the programm won't throw errors but it simply won't do anything anymore after this line.
Thanks in advance for any help!!!
function findLinkEntities(contentBlock, callback, contentState){
contentBlock.findEntityRanges((character) => {
const entityKey = character.getEntity();
return(
entityKey !== null &&
contentState.getEntity(entityKey).getElementById() === 'LINK'
)
}, callback);
}
const Link = (props) => {
const { url,linkText} = props.contentState
.getEntity(props.entityKey)
.getData()
return (
<a style={{color: '#006cb7', textDecoration: 'underline'}}
href={url}>
{linkText || props.children}
</a>
)
}
const linkDecorator = new CompositeDecorator([
{
strategy: findLinkEntities,
component: Link,
}
])

How to use getElementsByClassName on dynamic html

What I'm trying to do is to get HTML tag by className on dynamic HTML that I fetched,
but it returns undefined. It works if I try to getElementByClassName("main-page") because that class isn't dynamic
const HomePage = () => {
const [pageData, setPageData] = useContext(PageContext)
useEffect(() => {
const allImages = document.getElementsByClassName("wp-block-column")
console.log([...allImages])
}, [])
//render fronpage
const renderMainPage = () => {
//map the data and check for the site url (www.siteurl.com = front page)
if (pageData) {
return pageData.map(page => {
if (window.location.origin + "/" === page.link) {
return <section dangerouslySetInnerHTML={{ __html: page.content.rendered }}></section>
}
})
}
}
return (
<h1 className="main-page"">{renderMainPage()}</h1>
)
}
export default HomePage
From what I see the problem in pageData in context, probably your default value to context's pageData is false and renderMainPage() is not going further then first "if" statement
But its not preferred to use document selectors, use refs in React instead.
Also from naming I see that you are trying to get images and not dom nodes, but with this logic you are going to get dom nodes. I'm sure there is better way/flow to access images you need than looking for them in nodes.
const elementsRef = useRef(data.map(() => createRef()));
you can you dynamic create ref to access or create random iniNumber Array then assing to you elements when select them
You can use this function that useLayoutEffect, you can modify your code like this,
useLayoutEffect(()=> {
document.getElementsByClassName("yourclassname")
})

react functional component does not render

function validate is supposed to return element if function getConjugation doesn't return error, the valid input is passed to getConjugation, but it just renders nothing in browser
import React from 'react'
import {getConjugation} from 'german-verbs'
import GermanVerbsDict from 'german-verbs-dict'
export default ({word})=>{
const renderVerbs =(w)=>{
return (
}
const validate = (w) =>{
try{
return(
<ul>
<li>{w.toLowerCase()}</li>
<li>{getConjugation(GermanVerbsDict, "haben",'PRASENS', 2,'S' )}</li>
<li>{getConjugation(GermanVerbsDict,"haben",'PRATERITUM', 1,'S' )}</li>
<li>{getConjugation(GermanVerbsDict, "haben",'PERFEKT', 1,'S', "HABEN")}</li>
</ul>)
}catch {return false}
}
return (
<div className="verb">{validate(word)}</div>
)
}
You may try 3 things
Complete the renderVerbs function since now is missing a bracket.
This part of code seems to be exported out. Have you added this component to where it suppose to be?
Check whether validate function is actually been called. Here is what I will do.
const validate = (w) =>{
console.log("the word is: ", w);
return(
<ul>
<li>{w.toLowerCase()}</li>
//if your function return an array
YourArray.map(elem => (
<li>{elem}</li>
))
</ul>)
}
}
return (
<div className="verb">{validate(word)}</div>
)
If it does work, add one extra block code each at a time until it comes to your original code mentioned here. Hope you may find which part is buggy in this process. Good luck.

How can I make some text from a json string bold?

I want to concatenate two strings in react such that the first displays bold and the second does not. I have the string I want bolded in a JSON file and I have the string I want to concatenate coming from backend API call. Here's my setup:
This is in a JSON file:
{ stuff: {
stuffIWantBolded: "bold text"
}
}
And my frontend looks like this:
render() {
// props for this component in which I'm rendering SomeComponent (see below)
const { data } = this.props
const { theStringFromBackend } = data
// a method to get the string that is working for me
const stuff = this.getTheStringFromTheJSON();
const textIWantToDisplay = `${stuff.stuffIWantBolded} ${theStringFromBackend}`;
return (
<SomeComponent someProp={textIWantToDisplay} />
);
};
That concatenates the two strings successfully. I've tried using .bold() at the end of stuff.stuffIWantBolded, but that apparently doesn't work, because then the string renders as <b>bold text</b> the string from backend (assuming that's what the string from backend says), with the HTML tags written out explicitly instead of rendering actual bold text. Is there something I'm missing? I don't think one can just make the string bold in the JSON...perhaps I need to use a regex? Any help would be greatly appreciated.
How about this:
return (
<>
<span style={{fontWeight: "bold"}}>{stuff.stuffIWantBolded}</span>
<span>{theStringFromBackend}</span>
</>
);
The <> and </> effectively allow you to return multiple items from one render function.
I would do it by using composition (I prefer the strong tag to b to make text bold):
render() {
// props for this component in which I'm rendering SomeComponent (see below)
const { data } = this.props
const { theStringFromBackend } = data
// a method to get the string that is working for me
const stuff = this.getTheStringFromTheJSON();
return (
<SomeComponent>
<p><strong>{stuff.stuffIWantBolded}</strong> {theStringFromBackend}</p>
</SomeComponent>
);
};
And in SomeComponent you will find the nested html inside props.children
for more info check here: https://reactjs.org/docs/composition-vs-inheritance.html
It turns out you CAN pass in a prop within a self-closing tag component the way I want to. Not sure if it's conventionally sound/overly bloated but it looks like this:
render() {
// props for this component in which I'm rendering SomeComponent (see below)
const { data } = this.props
const { theStringFromBackend } = data
// a method to get the string that is working for me
const stuff = this.getTheStringFromTheJSON();
const theBoldedText = `${stuff.stuffIWantBolded}`;
return (
<SomeComponent someProp={<span><b>{theBoldedText}</b> <span>{theStringFromBackend}</span></span>} />
);
};

How to Loop Through Firebase JSON in React

I have the following JSON Data coming out of Firebase RTDB:
{"\"1\"":{"itemDescription":"This is a description of the item.","itemName":"Item Name","itemValue":{"costAmount":200,"costType":"dol"}},
"\"2\"":{"itemDescription":"This is an item description.","itemName":"Item Name 2","itemValue":{"costAmount":500,"costType":"dol"}}}
and so on...
The data is parsed (json.parse) and stored a variable called parsedJSONData in state.
I've tried looping through it using other recommendations on this site and others, such as:
this.state.parsedJSONData.map(json => {
<div className="item">
<p>Item: {json.itemName}</p>
</div>;
});
And I'm getting errors like the below:
Line 68: Expected an assignment or function call and instead saw an expression no-unused-expressions
Any tips on what I can do? I know the data is parsed correctly, because if I output the contents of the parsedJsonData to the console, I can see the data is structured correctly?
Try Using forEach() instead of map()
You are not returning anything inside of your map(). Here you can look at the different ways to return values from an arrow function, but in short, data will be returned in these two forms:
json => json.itemName
json => {return json.itemName;}
Drop the {} inside of your map or throw a return inside like so:
this.state.parsedJSONData.map(({itemName}) =>
<div className="item">
<p>Item: {itemName}</p>
</div>
);
or
this.state.parsedJSONData.map(({itemName}) => {
return <div className="item">
<p>Item: {itemName}</p>
</div>;
});
Try this. I have tried this and it works for the your json Data.
render() {
var tempData = [];
const theDataWeHave = this.state.parsedJSONData;
for(var row in theDataWeHave){
var rowEntry = theDataWeHave[row];
tempData.push(rowEntry);
}
var renderVariable = tempData.map(function(item,index) {
return ( <RenderThisComponent key={index} item={item}/> )
})
}
return(
//your code for other stuff
{renderVariable} //Place this where you want to render the component
)
The component you want to render will be a separate functional component with props passed to it.
You can write in the same file or you can write in separate file and import+export
.I have done in the same file so it do not need to be exported or imported.
const RenderThisComponent = (props) => (
<div className="item">
<p>Item: {props.item.itemName}</p>
</div>
)

Categories

Resources