I want to put some xml in the DOM so that it can be accessed by another Component. But when I try to render it, I keep getting prop unknown errors, such as:
warning.js:36 Warning: Unknown prop colour on <category> tag. Remove this prop from the element. For details, see https://facebook.github.io/react/warnings/unknown-prop.html
I don't want React to interpret those attributes as props! It's just xml, not a react component!
This is the code I have:
class DefaultToolbox extends Component {
render() {
// static xml
return (
<xml id="toolbox" style={{display: "none"}}>
<category name="Logic" colour="#5C81A6" />
// ... etc etc
</xml>
);
}
}
return (<span dangerouslySetInnerHTML={{ __html: `<xml ..> ... </xml>` }}/>);
for more information: https://facebook.github.io/react/docs/dom-elements.html#dangerouslysetinnerhtml
Related
I have a React app, receiving the blog post data from external cms. The data is raw HTML as a string, like this:
<h1>hello</h1>
<img src="example.com/felan.jpg">
<p>some text</p>
<img src"example.com/another.jpg">
...
Now, I want to replace img HTML tag with a jsx component called Img (with capital I).
I do it with:
let postContentOptimized = post.replace("img", "Img");
<article dangerouslySetInnerHTML={{ __html: postContentOptimized }} />
But it automatically converts Img to img (changes PascalCase).
I also tried with other component names, and it throws this error:
React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.
I found a package called react-jsx-parser.
Its documentation isn't straightforward, thus I skipped it the first time I found it.
Here's how to do it if you're confused like me:
<JsxParser components={{ components used in your string }} jsx={the string you want to parse} />
example:
<JsxParser components={{ Img }} jsx="<Img src="hello.png /><p>hello</p>" />
I followed the instructions in https://github.com/vuejs/jsx to add JSX support in my Vue app. It does in fact work - it renders JSX, but for some reason does not render nested elements.
public render(h: CreateElement): VNode {
// This works as expected: it renders a div with "Hello"
return (
<div>
Hello
</div>
)
}
public render(h: CreateElement): VNode {
// This does *not* work as expected, it renders an empty div
return (
<div>
<span>Hello</span>
</div>
)
}
What am I doing wrong?
I've created a very simple Next.js-project with two pages.
Both pages include a basic layout component:
// Page Component
render() {
return (
<PageLayout>
This is page A
</PageLayout>
);
}
And PageLayout looks something like this:
// PageLayout
render() {
return (
<div>
<Header />
{this.props.children}
</div>
);
}
So both pages use PageLayout to render a basic template that also includes the same Header on both pages.
My problem is that the Header component is re-created when navigating between the two pages. I think this is bad not only from a performance point of view, but also because in this case all DOM-Nodes and all React components loose their local state.
So I would like to know if there is something I am missing or how we can create shared components between pages that are reused properly (at least if their state did not change, of course).
You have Two pages with common component:
Page A:
<A>
<Common />
</A>
Page B:
<B>
<Common />
</B>
From the React documentation:
Whenever the root elements have different types, React will tear down
the old tree and build the new tree from scratch. Going from <a> to
<img>, or from <Article> to <Comment>, or from <Button> to <div> - any
of those will lead to a full rebuild.
This is why you lose the state in Common (Header) component. Like I suggested in the comment you would have to use an external state like redux.
You have to create a component with the name of layout
// components/layout.js
import Navbar from './navbar'
import Footer from './footer'
export default function Layout({ children }) {
return (
<>
<Navbar />
<main>{children}</main>
<Footer />
</>
)
}
And then rap your _app.js component like this
// pages/_app.js
import Layout from '../components/layout'
export default function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
for more read https://nextjs.org/docs/basic-features/layouts
I'm new to React and I'm trying to figure out the purpose/use of <MyComponent></MyComponent> vs <MyComponent />. I can't seem to find information on anything except self-closing tags.
I've created a basic tab scroller as a JSFiddle using the self-closing <MyComponent /> and subsequent props, and I'm wondering if there's a better way to write in React than what I've done.
class TabScroller extends React.Component {
render() {
return (
<div className="tabScroller">
<div className="NavList">
<TabNav handleClick={this.handleNavClick} />
<TabList
tabs={this.state.tabs}
activeTab={this.state.activeTab}
scrollPosition={this.state.scrollPosition}
handleClick={this.handleTabClick}
/>
</div>
<TabContent content={this.state.tabs[this.state.activeTab].content} />
</div>
);
}
}
// ========================================
ReactDOM.render(
<TabScroller />,
document.getElementById('root')
);
In React's JSX, you only need to write <MyComponent></MyComponent> when the component has child components, like this:
<MyComponent>
<Child />
<Child />
<Child />
</MyComponent>
If there is nothing between <MyComponent> and </MyComponent>, then you can write it either <MyComponent/> or <MyComponent></MyComponent> (but <MyComponent/> is generally preferred). Details in Introducing JSX.
Just as a side note, you'd access those children in your component via the special props.children property. More in JSX in Depth: Children in JSX.
Note that this is very much not like HTML or XHTML. It's its own (similar) thing with different rules. For instance, in HTML, <div/> is exactly the same thing as <div>: A start tag, for which you must eventually have an end tag. Not so JSX (or XHTML). The rules for HTML are that void elements (elements that never have markup content, such as br or img) can be written with or without / before > and they never get an ending tag, but non-void elements (like div) must always have an ending tag (</div>), they cannot be self-closing. In JSX (and XHTML), they can be.
The purpose of self-closing tags is simply the fact that it is more compact. This is especially useful when said component doesn't have any children that you typically wrap around a parent.
So usually for leaf components (i.e compoents that do not have any children), you use the self-closing syntax. Like: <Component />. And even if it has props, you can do: <Component foo="bar" />.
However, remember that children is a prop, so you could technically do:
<Component children={<span>foo</span>} />
but I find it less readable and advise against it (read disclaimer below).
To summarize, these are equivalent:
<Component /> = <Component></Component>
<Component foo="bar" /> = <Component foo="bar"></Component>
<Component children={<span>foo</span>}></Component> =
<Component><span>foo</span></Component>
You can use whichever approach you prefer. Though praxis is to use the short-hand version when there are no children.
Disclaimer: While defining childen prop by its object key value will technically work, doing so is strongly discouraged as it disrupts the API as it is meant to be used. Use this version only if confident in what you are doing.
I have to render an HTML template using reactjs. HTML template is dynamic and get through an API call. There is provision in template to bind the data in html.
Sample HTML template is as follows,
<a target="_blank" href="{ad.url}">
<div class="ads temp-1">
<h2>{ad.name}</h2>
<div class="adv-content">
<div class="advs-image">
<img src="{ad.image}" />
</div>
<div class="adv-desc">{ad.description}</div>
</div>
</div>
</a>
Here ad is an Object which contains the properties url, image, name, description etc
Sample ad Object is as follows,
var ad = {
"image": "testimage.jpg",
"url": "http: //google.com",
"name": "testadvertisement",
"description": "testdescription"
}
I have achieved this in AngularJs using, $compile service.
Now I want to move this to reactjs.
I have tried to render using reactjs render function, But it didn't help. It renders html as string.
Is there any compile like function in reactjs ? Or could you please suggest any other way to do this right way ?
Any help appreciated.
As I correctly undestand you should use dangerouslySetInnerHTML prop.
For example:
// SomeComponent.js
// other methods...
render() {
// `htmlFromResponse` is your plain html string from response.
return (
<div dangerouslySetInnerHTML={{ __html: htmlFromResponse }} />
);
}
Using this prop, you can render plain html string into div element.
If you are getting html template from server, and want to pass variable to it before rendering, you can do it with Mustache package:
import Mustache from 'mustache';
// template should contain variables in {{ ... }}
const html = Mustache.render(htmlFromServer, {
variable: 'value'
});
Next, you can render output html using dangerouslySetInnerHTML prop.
create a react component which renders the HTML data, then pass your Json data as Prop to the component. this will give React element access to data and Rendered HTML will be automatically updated when Json data changes.
Check out some react tutorial video over youtube, that will give you an overview of how ReactJs works
here is how to Pass Props
https://jsfiddle.net/abhirathore2006/6a403kap/
var Hello = React.createClass({
render: function() {
console.log(this.props)
return <div>Hello {this.props.name}
<h5>{this.props.d1.name}</h5>
id:{this.props.d1.id}
</div>;
}
});
ReactDOM.render(
<Hello name="World" d1={{"name":"test","id":"5"}} />,
document.getElementById('container')
);