Custom namespaced attribute in JSX/React - reactjs

As I already figured out, React's JSX doesn't support namespace tags by default. But lets say I have the following component:
render() {
return (
<div><!-- This should contain th:text -->
...
</div>
);
}
and I want this component to be rendered to:
<div th:text="value">
...
</div>
How can I achieve, that th:text="value" will be added to the rendered output?

Found the solution a few minutes later:
const i18n = {
"th:text": "${#foo.bar}"
};
render() {
return (
<div {...i18n}>
...
</div>
);
}

Related

How to modify this to not be two components in React

NOTE: I HAVE REPLACED THIS QUESTION WITH ONE WITH MORE CLARITY AT THE LOCATION: Context not returned when referencing React component as function instead of JSX
I WOULD LIKE TO DELETE THIS BUT SO WILL NOT LET ME.
I have the following JavaScript file that is one React component calling another one nested inside it. I want to change this to not use the name of the nested component but instead create the internal component as an anonymous one.
I want to usr the JavaScript name and not return JSX.
Here is my original working component
const InsideComponent = () => {
return (
<div>
Inside Component
</div>
);
};
export default function Speakers() {
return (
<div>
<InsideComponent />
</div>
);
}
I've tried a few combinations including this below that do not work
export default function Speakers() {
return (
<div>
{
return (
{ InsideComponent()}
)
}
</div>
);
}
Using { inside the context of JSX stops the JSX syntax and begins a plain JavaScript expression. (Not a function - no return.) So from here
<div>
{
for the syntax to be valid, you'd need to have an expression that evaluates to a JSX element:
export default function Speakers() {
return (
<div>
{
(
<div>
Inside Component
</div>
)
}
</div>
);
}
But the nesting of a JavaScript expression isn't useful at all there - better to just insert the plain JSX instead.
export default function Speakers() {
return (
<div>
<div>
Inside Component
</div>
</div>
);
}
When you want to merge components, you just need to merge the JSX portion of it.
In your example, you can just do
export default function Speakers() {
return (
<div>
<div>
Inside Component
</div>
</div>
);
}
Why not this?
export default function Speakers() {
return (
<div>
<div>
Inside Component
</div>
</div>
);
}
Unless you're using the InsideComponent as part of other components, there is no need to separate the two. But if you want to, just use it like you would any other component.
export default function Speakers() {
return (
<div>
<div>
<InsideComponent />
</div>
</div>
);
}
export default function Speakers() {
return (
<div>
<div>
Inside Component
</div>
</div>
);
}
Is this is what you are looking for?

How to display the html of the children slot?

I've got this react component where I'm passing in a title and the children is a simple div with the word test.
export default function Home() {
return (
<div>
<main>
<SourceCode title="Header">
<div>test</div>
</SourceCode>
</main>
</div>
);
}
I want to display the HTML of whatever is in the children slot so in this example I want to to show <div>test</div>, I've tried using pre but I get the error TypeError: Converting circular structure to JSON
export default function SourceCode({ children, title }) {
return (
<div>
<div>{title}</div>
<div>{children}</div> // <== Here I want to render the markup, this works
<div>
<pre>{JSON.stringify(children)}</pre> // <== Here I want to show the markup
</div>
</div>
);
}
I have also tried
<pre>
<code>{children}</code>
</pre>
but this just shows test and I want it to show <div>test</div>
You could try with ReactDOMServer.renderToStaticMarkup
import ReactDOMServer from 'react-dom/server';
export default function SourceCode({ children, title }) {
const markup = ReactDOMServer.renderToStaticMarkup(children);
return (
<div>
<div>{title}</div>
<div>{children}</div> // <== Here I want to render the markup, this works
<div>
<pre>{markup}</pre> // <== Here I want to show the markup
</div>
</div>
);
}

React - Extremely simple Codepen will not show up

I have a codepen. I need it to literally say "Hello world" with React. I can't get the code to render.
I have Babel set as the pre-compiler.
I have both React and ReactDOM linked.
Here is all of the HTML:
<div id="app"></div>
Here is all of the JS:
class App extends React.Component {
render() {
<div>
<p>Hello!</p>
</div>
}
}
ReactDOM.render(<App />, document.getElementById('app'));
I need to get this going for an interview in an hour or two. Just can't get it working here. Help!
You forgot to return the component in render:
render() {
return (
<div>
<p>Hello!</p>
</div>
);
}
You need to return the content from the render function to display.
class App extends React.Component {
render() {
return (
<div>
<p>Hello!</p>
</div>
}
}

Implement HTML Entity Decode in react.js

I am outputting the text using API from the server, and I have an admin which has the html fields for facilitating filling the content. The issue in here that now the text displaying with html codes. How I can get rid of that undeeded html codes. I guess I have to use html entity decode? How I will implement that in react project? Below you see that the text illustrates not only text and html code.
export class FullInfoMedia extends React.Component {
render() {
const renderHTML = (escapedHTML: string) => React.createElement("div", { dangerouslySetInnerHTML: { __html: escapedHTML } });
return (
<div>
<div className="about-title">
<div className="container">
<div className="row">
<img className="center-block" src={this.props.about.image}/>
<h2>{this.props.about.title}</h2>
{renderHTML(<p>{this.props.about.body}</p>)}
</div>
</div>
</div>
</div>
);
}
}
You can use dangerouslySetInnerHTML, but be sure you render only your input, not users. It can be great way to XSS.
Example of using:
const renderHTML = (rawHTML: string) => React.createElement("div", { dangerouslySetInnerHTML: { __html: rawHTML } });
And then in a component:
{renderHTML("<p>&nbsp;</p>")}
Even though you can use dangerouslySetInnerHTML it's not really a good practice, and as stated by Marek Dorda it's a great thing for making your app XSS vulnerable.
A better solution would be to use the he library. https://github.com/mathiasbynens/he
This would be an example of how would your component look with it.
import he from 'he'
export class FullInfoMedia extends React.Component {
render() {
const renderHTML = (escapedHTML: string) => React.createElement("div", { dangerouslySetInnerHTML: { __html: escapedHTML } });
return (
<div>
<div className="about-title">
<div className="container">
<div className="row">
<img className="center-block" src={this.props.about.image}/>
<h2>{this.props.about.title}</h2>
{ he.decode(this.props.about.body) }
</div>
</div>
</div>
</div>
);
}
}
Also, if it were my codebase, I would most likely move the decoding to the API call, and in the component just consume the value that comes from the store
You can simply try this, it decodes text and then display.
<p dangerouslySetInnerHTML={{__html:"&nbsp;"}}/>

Element not being displayed when div is removed in react

I am quite new to react but I am trying to pass element from the Course component to my Coursebox component. I am doing this successfully but the button is being displayed since I am not passing that with this.prompt. I would like to remove the div id="course" from the HTML because I only want the course component to be displayed within the couresebox component.
This is my JSX code
class Course extends React.Component {
render() {
return (
<div className="course">
<h3>{this.props.coursename}</h3>
<h4> {this.props.status} {this.props.progress}</h4>
<button>Start exercise</button>
</div>
);
}
}
ReactDOM.render( < Course />, document.getElementById('course'));
class Coursebox extends React.Component {
render() {
return (
<div>
<Course coursename="Negotiation" progress= "20%" status="Progress"/>
<Course coursename="Frontend" progress="56%" status="Progress"/>
<Course coursename="Food" status="Progress" progress="43%"/>
</div>
);
}
}
ReactDOM.render( < Coursebox />, document.getElementById('coursebox'));
and HTML
<header id="header">
</header>
<h3 id="search"></h3>
<div id="coursebox"></div>
<div id="course"></div>
When I remove the nothing is being displayed on the page apart from the header. Since I am passing the element from Course to the Coursebox component, shouldn't I be able to remove the course div from the HTML?
If it is still needed, why is that?
Is there a way for me to only display the button when a course name is being passed?
Thanks :)
Avoid rendering the course component. Ideally there should be just one render method and all other components should be called from that component. So render on CourseBox component only.
class Course extends React.Component {
render() {
console.log("hey")
return (
<div className="course">
<h3>{this.props.coursename}</h3>
<h4> {this.props.status} {this.props.progress}</h4>
<button>Start exercise</button>
</div>
);
}
}
class Coursebox extends React.Component {
render() {
return (
<div>
<Course coursename="Negotiation" progress= "20%" status="Progress"/>
<Course coursename="Frontend" progress="56%" status="Progress"/>
<Course coursename="Food" status="Progress" progress="43%"/>
</div>
);
}
}
React.render(<Coursebox />, document.getElementById('coursebox'));
Working JS fiddle http://jsfiddle.net/kmbw9wgt/3/
1.) See this line
ReactDOM.render( < Course />, document.getElementById('course'));
You are explicitly asking react to render Course in a div which has id 'course'.
If you remove this, it will not render separately, but only from within Coursebox element.
Then you can safely remove that div.
2.) Yes, you can only show button when course name is passed. Using If condition ternary operator. Add your button in following way:
<h3>{this.props.coursename}</h3>
<h4> {this.props.status} {this.props.progress}</h4>
{ this.props.coursename ? (<button>Start exercise</button>): null}

Resources