Render a react.js component with document.write() inside - javascript

I am trying to render a component which uses document.write() inside, as I have to convert a json string to HTML. The problem I face is that when doing this the component only renders what is inside the document.write().
The code is the following:
render() {
return (
<div>
<Header />
<div className="main-wrapper">
<Link className="back-home" to="/">
All news
</Link>
{this.state.articles.map(articulo => {
console.log(articulo.content.rendered);
return (
<article className="article-wrapper" key={articulo.id}>
<h1>{document.write(articulo.title.rendered)}</h1>
<span className="article-date">
{this.dameFecha(articulo.date)}
</span>
<img
className="article-image"
src={
articulo.better_featured_image.media_details.sizes.small
.source_url
}
/>
<div className="article-content">
{document.write(articulo.content.rendered)}
</div>
</article>
);
})}
</div>
</div>
);
}
None of the elements are shown this way. I have already tried to put inside the document.write() all the elements, but React doesn't allow to do that. I mean doing this:
render() {
return (document.write(/* all the code */))
}
Is there any way to solve this?

You could use dangerouslySetInnerHTML to render your string of HTML:
<h1 dangerouslySetInnerHTML={{ __html: articulo.title.rendered }} />

Related

Getting this React.Children.only expected to receive a single React element child error for using <Link> in Next.js

I have below code. It's giving me error
Error: React.Children.only expected to receive a single React element child.
As i try to resolve it,its allowing me only one header under link.
<div className="container">
{cards.map(card => (
<div className="grid-item">
<Link href={'/ninjas/' + card.id} key={card.id}>
<h1>{ card.reporter }</h1>
<h3>{ card.title }</h3>
</Link>
</div>
))}
</div>
Please first of all read this: Why React.Children.only?
The issue can be fixed by doing this:
<div className="container">
{cards.map(card => (
<div className="grid-item">
<Link href={'/ninjas/' + card.id} key={card.id}>
<div>
<h1>{ card.reporter }</h1>
<h3>{ card.title }</h3>
</div>
</Link>
</div>
))}
</div>
In general, Link is a component, and as you can read in the docs of react docs or the link I provided, children should always be nested in one element. The same is true for what every React component should return.

extends/inherit parent component in function

export default function PageTemplate() {
return (
<div className="layout">
<LeftMenu />
<div className="content">
<TopMenu />
<div id="other-contents">
// Contents goes here
</div>
</div>
</div>
);
}
export default function Index() {
return (
<div className="layout">
<LeftMenu />
<div className="content">
<TopMenu />
<div id="other-contents">
<h2>I am Index Page<h2/>
</div>
</div>
</div>
);
}
As you can see most of my contents goes in #other-contents, I will be repeating PageTemplate for every page, I wondering if there is way to just re-use PageTemplate. Instead of repeating code, I would just do something like extends/inherit/whatever possible and reduce the code in Index
I believe this is easier achieved with Class Based Component. But I am wondering if there could function based solution
React prefers Composition over Inheritance. Use the children prop all react components have.
export default function PageTemplate({ children }) {
return (
<div className="layout">
<LeftMenu />
<div className="content">
<TopMenu />
<div id="other-contents">
{children}
</div>
</div>
</div>
);
}
Usage:
<PageTemplate>
// <-- render any content you want here
</PageTemplate>

How to make images fit the page in React/Bootstrap?

I am using a function that maps every item in the props array to creating an image tag. I am trying to make every 3 images have a row div around them using bootstrap so they will fit the page correctly, but I cannot figure out how to do it. Any help would be appreciated. Here is the code:
import React, { Component } from 'react';
import "./Skills.css";
export default class Skills extends Component {
static defaultProps = {
images: [
"https://upload.wikimedia.org/wikipedia/commons/thumb/6/61/HTML5_logo_and_wordmark.svg/1200px-HTML5_logo_and_wordmark.svg.png",
"https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/CSS3_logo_and_wordmark.svg/1200px-CSS3_logo_and_wordmark.svg.png",
"https://upload.wikimedia.org/wikipedia/commons/6/6a/JavaScript-logo.png",
"https://p7.hiclipart.com/preview/306/37/167/node-js-javascript-web-application-express-js-computer-software-others.jpg",
"https://bs-uploads.toptal.io/blackfish-uploads/skill_page/content/logo_file/logo/5982/express_js-161052138fa79136c0474521906b55e2.png",
"https://webassets.mongodb.com/_com_assets/cms/mongodb_logo1-76twgcu2dm.png",
"https://www.pngfind.com/pngs/m/430-4309307_react-js-transparent-logo-hd-png-download.png",
"https://botw-pd.s3.amazonaws.com/styles/logo-thumbnail/s3/012015/bootstrap.png?itok=GTbtFeUj",
"https://sass-lang.com/assets/img/styleguide/color-1c4aab2b.png"
]
}
photo() {
return (
<div >
{this.props.images.map(image => (
<div className="col-md-4">
<img className="photo" src={image} />
</div>
))}
</div>
);
}
render() {
return (
<div id="skills-background" className="mt-5">
<div id="skills-heading" className="text-center">Skills I've Learned:</div>
<div className="container">
<div className="row">
{this.photo()}
</div>
</div>
</div>
)
}
}
CodeSandbox
I think, I found the issue,
<div> <-----This div is the issue
{this.props.images.map(image => (
<div className="col-md-4">
<img className="photo" src={image} />
</div>
))}
</div>
You have wrapped your col-md-4 with a div, and div has display: block style, so you are getting every image on separate row. Simply replace div with Fragments,
<> <-----Make it Fragment
{this.props.images.map(image => (
<div className="col-md-4">
<img className="photo" src={image} />
</div>
))}
</>

How to disable footer in one of the React JS views without creating new layout?

I have about 20 views that use the same layout. Now i need 1 page which does not use footer. First idea i had is to create a new layout but this does not seem like a good way to do this.
LAYOUT
const App = () => (
<div className="full-container">
<Router history={Router}>
<Main>
<STUFF HERE>
</Main>
</Router>
<Footer/>
</div>
);
VIEW
render()
{
return (
<div>
<h1 className="section-smaller-title">TITLE</h1>
<STUFFHERE>
</div>
</div>
);
}
FOOTER COMPONENT
render() {
return (
<footer>
<img alt="footer logo" className="footer-logo" src="imgsurl"/>
</footer>
);
}
}
How can i not show this Footer in that view?
I tried it with
document.getElementByClassName(...)
But this disabled it everywhere.
What is the standard way of doing this?
You can use Conditional Rendering, specifically Inline If with Logical && Operator. Just change your layout to this:
const App = () => (
<div className="full-container">
<Router history={Router}>
<Main>
<STUFF HERE>
</Main>
</Router>
{location.pathname !== “URL path where you don’t want to see footer” && <Footer/>}
</div>
);
More info about Conditional Rendering at https://facebook.github.io/react/docs/conditional-rendering.html#inline-if-with-logical--operator Hope it will help.

React rendering output from 'Marked' as text

I am using the Marked library with React. The problem I am having is that output from Marked renders as text when it included proper HTML elements. Here is the problem Code:
class Main extends React.Component{
render() {
console.log(this)
console.log(marked('I am using __markdown__.'));
return (
<div className="container">
<div className="row">
<div className="col-md-6">
{marked('I am using __markdown__.')}
</div>
<div className="col-md-6">
<h1>Oh hello</h1>
</div>
</div>
</div>
)
}
};
React.render( <Main />, document.getElementById('app'));
and the html:
<div id="app"></div>
thanks.
Use dangerouslySetInnerHTML. React prevents you from xss, and this is the escape hatch.
<div
className="col-md-6"
dangerouslySetInnerHTML={{
__html: marked('I am using __markdown__.')
}}
/>

Categories