React component in another component - reactjs

I'm beginner in React, but have to ask this question because I can't find answer
This is my code
class UserLogin extends React.Component{
render(){
const {title} = this.props
return(
<p> {title} </p>
);
}
}
class UserGuide extends React.Component{
render(){
return(
<p> Test class </p>,
<UserLogin title = "Nexicolt" />
);
}
}
ReactDOM.render(
<UserGuide/>,
document.getElementById('app')
);
Output is
Nexicolt
not
test class
Nexicolt
Why ?

Notice that a comma after <p> is located outside JSX, so it's JavaScript syntax and not HTML text node.
Comma operator ignores the first part of an expression, <p> Test class </p>, and returns only the second part from render functon, <UserLogin title = "Nexicolt" />.
If there are multiple children elements, either an array should be returned:
return [
<p> Test class </p>,
<UserLogin title = "Nexicolt" />
];
Or a fragment:
return <>
<p> Test class </p>
<UserLogin title = "Nexicolt" />
</>;
If you are not sure you have good uses for comma operator, ESLint no-sequences rule can be used to prevent it from being used and avoid potential mistakes.

If you are using React 16.* then you can use fragment:
return <>
<p> Test class </p>
<UserLogin title = "Nexicolt" />
</>;
or return array
return [
<p> Test class </p>,
<UserLogin title = "Nexicolt" />
];
and if you are using React below 16 then wrap it inside div as follows:
return (
<div>
<p> Test class </p>,
<UserLogin title = "Nexicolt" />
</div>
);

You are having Comma operator in the render function, it will only take the last part of the render function.
<p> Test class 1</p>,
<UserLogin title = "Nexicolt" />,
<p> Test class 2</p>
This will return the result 'Test class 2'.

Related

React replace comma with a new line

How to I replace the comma with a new line?
Want to be like this
Example
My code
<p className='containerProductDetailsPOne' style={{ overflow:"hidden",overflowY:"scroll" }}>
{location.state.product.productSpec}
</p>
I tried
{location.state.product.productSpec.replace(/,/g, '<br>')}
and
{location.state.product.productSpec.replace(/,/g, '\n')}
but does not work
Using replace is not possible to achieve what you want because react just renders the content, not the HTML or neither the HTML tags.
An alternative approach to solve this problem is to split the text using the comma separator as a parameter and display every single content of the resulting array like this:
let text = "Lorem Ipsum is simply, dummy text of the printing"
return (
<div>
{text.split(",").map((substring, idx)=> {
return (
<div key={idx}>
<span>{substring}</span>
<br />
</div>
}
</div>
You can check my example on my code sandbox: https://codesandbox.io/s/awesome-ritchie-y9j9j2?file=/src/App.js:796-911
Please use below code snippet
import React from "react";
class ProductSpec extends React.Component
{
constructor(props)
{
super(props)
}
render()
{
let productSpec='Product 1, Product 2, Product 3'
return(productSpec.split(",").map(p=><p key={p}>{p}</p>));
}
}
ProductSpec.displayName='ProductSpec'
export default ProductSpec;
try this
let text = "Lorem Ipsum, Is simply, dummy text, of the printing"
return (
<div>
{text.split(",").map((substring, index)=> {
return (
<div key={index}>
<span>{substring}</span>
</div>
}
</div>

Is it possible to render a react class when given its name as a string?

Here's a smaller example of what I'm trying to do, I don't know if it's possible to do something similar or I should use an entirely different method.
import {Design1, Design2} from './page-designs';
let designs = {
"page1":"Design1",
"page2":"Design2",
"page3":"Design1",
"page4":"Design2"
}
class DesignedPage extends React.Component {
let Design = designs[this.props.page]
render(){
return(
<div className="row flex-fill d-flex">
<div className="col-1"></div>
<Design /* This is the line that fails */
data = {this.props.data}
/>
</div>
</div>
)}
}
class Main extends React.Component {
render(){
return(
<DesignedPage
page = {this.props.openPage} /*this could be any of page1-4 depending on button a click*/
data = {this.props.data}
/>
)}
}
Ideally this would render the react elements Design1 or Design2 based on what props.page is passed, but instead it returns
"Warning: <Design1 /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements." and "The tag <Design1> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter."
I've thought of making a long if, elseif, elseif.. statement in DesignedPage (the actual code has many more than 2 designs), which I'm fairly confident would work, but looks very messy in comparison.
You can't render the component name by getting its name as a string. You need to map the string to the component iteself:
let designs = {
"page1":Design1,
"page2":Design2,
}
If you pass a string, react would think it's a HTML tag, hence it say'Design1' tag is unrecognised. Also, you could import the components and use them as values in the designs object in place of strings.
let designs = {
"page1":Design1,
"page2":Design2,
"page3":Design1,
"page4":Design2
}
make one function that return react component..
getComponent = ({data, pageName}) => {
if(pageName === "page1") return <Desig1 />;
if(pageName === "page2") return <Design2 />;
}
and call function from render of DesignedPage component
const {page, data} = this.props;
return(
<div className="row flex-fill d-flex">
<div className="col-1">
{getComponent(page, data)}
</div>
</div>
)

How to change the state in conditional - React

I need to change the state of sibling components in my React App.
I use state and setstate
I need to change the state of sibling components. When loading the page, there must exist (visible in the page) <BkUser /> and when clicking "button id =" ds-visual "it must be deleted (<BkUser /> mustn't exist) and there must exist <BkDescanso />.
When you click on <BkSleep /> (in the div parent) you should remove <BkDescanso /> and show <BkUser />
This is the web.
There should never be <BkUser/> and <BkSleep> at the same time. <Bkuser /> is the blue block and <BkDescanso /> is the red block
This is my code:
Edit: I edit my original code because I fix the problem. This is the final OK Code. In the end the most important thing was the state conditional
{
this.state.usuario ? (<BkUser handleClick = {this.handleClick} usuario={this.state.usuario}/>): (<BkDescanso handleClick = {this.handleClick} usuario={this.state.usuario}/>)}
import React, { Component } from 'react';
class Header extends Component {
constructor(props) {
super(props);
this.state = {
usuario: true,
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(state => ({
usuario: !state.usuario
}));
//alert("Works button");
}
render(){
return (
<header className="header">
<div className="configuracion">
{
this.state.usuario
? (
<BkUser handleClick = {this.handleClick} usuario={this.state.usuario}/>
)
: (
<BkDescanso handleClick = {this.handleClick} usuario={this.state.usuario}/>
)}
<div className="content-btn">
<button id="config" className='btn btn--rounded'><span className="ico-configuracion"></span></button>
<button id="salir" className='btn btn--rounded'><span className="ico-exit"></span></button>
</div>
</div>
</header>
);
}
}
class BkUser extends Component{
render(){
return ((
<div className='usuario'>
<img src="../img//usuario.svg" alt="Imagen usuario"/>
<div className="content-usuario">
<span id="nm-usuario" className="h4">Hermione Jane Granger</span>
<span id="tp-usuario" className="h5">Supervisor</span>
</div>
<div className="content-descansos">
<div className="botones">
<button id="ds-visual" className='btn btn--rounded' onClick={this.props.handleClick}><span className="ico-visual"></span></button>
<button id="ds-admin" className='btn btn--rounded'><span className="ico-tiempo-administrativo"></span></button>
<button id="ds-otros" className='btn btn--rounded'><span className="ico-descanso"></span></button>
</div>
<div className="ds-actual">
<span id="ds-tipo">Administrativo</span>
<span id="ds-tiempo">00:08:47</span>
</div>
</div>
</div>
));
}
}
class BkDescanso extends Component {
render(){
return ((
<div className='usuario descanso' onClick={this.props.handleClick}>
<h3>Finalizar descanso</h3>
</div>
));
}
}
export default Header;
Right now handleClick works but always exist BkUser and BkDescanso. I need only one to exist. If you click on id = "ds-visual" the bkUser block should disappear and BkDescanso appear. Then if you click on div className = 'user rest' in BkUser there should only be BkDescanso.
I think that it is not able to know when it is true and when it is false to show or hide
Thanks a lot for the help.
You're missing two things:
First you have to pass the handleClick function to the BkUser component, and then you have to call it via this.props.handleClick.
...
<BkUser handleClick={this.handleClick} usuario={this.state.usuario} />
....
<button
id="ds-visual"
className="btn btn--rounded"
onClick={this.props.handleClick}
>
ds-visual
<span className="ico-visual" />
</button>
CodeSandbox here.
Read more here.
You can change the state of the siblings by passing a function from the parent via props into them.
In the end your siblings are the children of their parent.
You can read this articles on how to change the state of child components.
React js change child component's state from parent component
https://medium.freecodecamp.org/react-changing-state-of-child-component-from-parent-8ab547436271
An other thing you could look into would be React Redux.

ReactJS- Only latest line of text is appearing in web page

I have this class function
class Fact extends React.Component {
render() {
return (
<img src="Logo.png"/>,
<center><p>FACT</p></center>,
<h1>Hello</h1>
)
}
}
export default Fact;
When running my localhost server, only "Hello" appears on the webpage. The logo doesn't appear, or the text message "FACT". Only "Hello" appears...How do I fix this?
Im trying to fit in 3 paragraphs as text to appear on my website, along with the logo. What's the best practice for this, rather then spam ?
You need to wrap the render output within a "root element", such as a <div> element to ensure that reactjs renders all the contents of the Fact component as you are expecting.
See the comments and code below, showing how to correct the error:
class Fact extends React.Component {
render() {
return (
<div> {/* Add <div> opening tag here */}
<img src="Logo.png"/>,
<center><p>FACT</p></center>,
<h1>Hello</h1>
</div> {/* Add </div> closing tag here */}
)
}
}
Note also that </h1> is missing the > in your question. This has been corrected in my answer
In React, if you're rendering multiple nodes (e.g. img, center, h1), you need to nest them under one parent node, e.g. <div>. That is, you can only return one top level node from your render function.
So:
class Fact extends React.Component {
render() {
return (
<React.Fragment>
<img src="Logo.png" /> ,
<center>
<p>FACT</p>
</center>
<h1>Hello</h1>
</React.Fragment>
);
}
}
Note that React.Fragment could also be something like a div.

React: how to comment HTML inside a render method

(Sorry if too obvious and/or dup, couldn't find original one...)
How should I be able to comment out TodoTitle below? I tried with <!--...-->, //, /*...*/ with no luck.
class TodoApp extends React.Component {
render() {
return (
<div className="todo-app">
<TodoTitle />
</div>
);
}
}
You can comment {/* comment */} in JSX.
Can you not just use {/* stuff */} ?

Resources