I have a Route that has a component with this in its render() :
<div>
<Nav/>
{this.props.children}
<Footer/>
</div>
How do I give all components that are rendered through it as children a className?
I've tried this:
<div>
<Nav/>
{React.cloneElement(this.props.children || <div />, { className: 'test' })}
<Footer/>
</div>
but it doesn't work.
I'm assuming the className went on the Route component instead of the component that was passed to the Route component?
Related
I want to make my code cleaner and set a styled component inside JSX code...
Example:
const MyDiv = styled.div`background-color: red;`;
const MyComponent = () => { return (
<div>
<h1>Title</h1>
<MyDiv>
Some stuff...
</MyDiv>
</div>
)}
Is there a way to insert the MyDiv direct inside the JSX code, or do I need to declare it on the component?
I think you should declare it on the component. if you don't want to declare it on the component, you can insert it directly as div
Here is an example of it. Please check below.
const MyComponent = () => { return (
<div>
<h1>Title</h1>
<div style={{backgroudColor: 'red'}}>
Some stuff...
</div>
</div>
)}
If you want your seamless effect, make a new component file for your div, style it the way you want in there, then import your new div at the top of the file.
Declare a component and wrap the children like this:
const MyDiv = ({children}) => {
return <div style={{backgroundColor: 'red'}}>{children}</div>;
};
And use it
<MyDiv>
<p>test</p>
</MyDiv>
I have been trying to create a JSXComponent with some functionalities inside that return a JSX element as a parent.
I want something like this:
<JSXComponent someProp="value">
{({data, loading, error})} => (
<div className="Parent">
some html code...
</div>
)
</JSXComponent>
but on the output, it only returns the JSX element that returns in JSXComponent and not the contents of a function inside that JSXComponent
The result is like this:
<div className="JSXComponent">Some...</div>
Try like this using a higher order component.
const hocWrapWithParent = ({ChildComponent}) => props => (
<div className="Parent">
<ChildComponent {...props} />
</div>
);
const ChildComponent = ({someprop) => <div>some child with prop= {someprop}</div>;
const Wrapped = hocWrapWithParent({ChildComponent});
// <Wrapped someprop={'hello'} />
When writing classic html we usually put our elements in a div and give this div a class name or id.
But in react, we place our elements in an empty div. We do not give both id and class name to this div.
What is the main reason for this? Can you explain?
My code sample is below.
Empty div code example
`
import classes from '../Input/Input.module.css';
const LoginPage = () => {
return (
<div>
<div className={classes['login-page']} >
<form>
<h1 className={classes['login-header']} >Login</h1>
<div className={classes.block}>
<label>Email:</label>
<input type="email"
className={classes['classes-inputs']} />
</div>
<div className={classes.block}>
<label>Password:</label>
<input type="password"
className={classes['classes-inputs']}
/>
</div>
<div className={classes.block}>
<input type="submit" value="Login" />
</div>
</form>
</div>
</div>
)
}
export default LoginPage;
`
Non-empty div code sample
`
import classes from '../Input/Input.module.css';
const LoginPage = () => {
return (
<div className={classes['login-page']} >
<form>
<h1 className={classes['login-header']} >Login</h1>
<div className={classes.block}>
<label>Email:</label>
<input type="email"
className={classes['classes-inputs']} />
</div>
<div className={classes.block}>
<label>Password:</label>
<input type="password"
className={classes['classes-inputs']}
/>
</div>
<div className={classes.block}>
<input type="submit" value="Login" />
</div>
</form>
</div>
)
}
export default LoginPage;
`
You don't have to actually.
The only limitation is that you must return a single element, so in the case you don't have a wrapper already you put an empty div around.
If you don't want to have an empty div you can use fragments <></> to wrap your elements
In most cases the wrapper div is “irrelevant” and is only added because React components require you to return only one element. This kind of behaviour results in useless markup and sometimes even invalid HTML to be rendered, which is bad.
For example we could have a component Table that renders an HTML table and inside that table the columns are rendered with another component called Columns. It would probably look something like this.
`
class Table extends React.Component {
render() {
return (
<table>
<tr>
<Columns />
</tr>
</table>
);
}
}
class Columns extends React.Component {
render() {
return (
<div>
<td>Hello</td>
<td>World</td>
</div>
);
}
}
`
This would result in an invalid HTML to be rendered because the wrapper div from Columns component is rendered inside the .
`
<table>
<tr>
<div>
<td>Hello</td>
<td>World</td>
</div>
</tr>
</table>
`
React fragments let you group a list of children without adding extra nodes to the DOM because fragments are not rendered to the DOM. So basically we use React.Fragment where we would normally use a wrapper div.
We can make use of fragments with <React.Fragments> syntax. So we could write the Columns component as follows.
`
class Columns extends React.Component {
render() {
return (
<React.Fragment>
<td>Hello</td>
<td>World</td>
</React.Fragment>
);
}
}
`
The problem here is JSX parser I think.
JSX and React can return only one component so we can not do something like below
return (
<ComponentA />
<ComponentB />
<ComponentC />
)
You must put a outermost wrapper for all of them and most of the time we use <div> tag
return (
<div>
<ComponentA />
<ComponentB />
<ComponentC />
</div>
)
But you can use React.Fragment or its shortcut <> for opening tag and </> for closing tag.
return (
<> // Can replace with <React.Fragment>
<ComponentA />
<ComponentB />
<ComponentC />
</> // Can replace with </React.Fragment>
)
There is some different between using <div> and React.Fragment. You can read it here Why are Fragments in React 16 better than container divs?
No need to do it. If you consider JSX to be just functions of React.createElement(...) you can structure the tree you are building in JSX entirely with functions inside functions (hof).
Example:
return React.createElement('div',{
children: React.createElement('div',{
className: classes['login-page'],
children: React.createElement(/* and so on */)
})
})
You can immediately see that you can have started this "creation" of a tree at the second level of the divs. You can also see why the following is not possible similar to the other answers:
return (
React.createElement('div',{})
React.createElement('div',{})
React.createElement('div',{})
)
And no, you don't need to return a single element. You could wrap that for valid javascript into:
return [
React.createElement('div',{ key: 'some_id_1' }),
React.createElement('div',{ key: 'some_id_2' }),
React.createElement('div',{ key: 'some_id_3' })
]
That's why you should wrap everything into a fragment <></>, array or a single wrapper component/jsx-tag. Note the key attribute - React can do some optimisation magic with it.
I need to modify the styles of the child component from the parent component. But the styles defined in the parent class are not getting reflected in the child component ? What can be the possible approach?
Component2 ( Child Component )
<div className={ classNames(css.class2, this.props.classWrapper) }>
<div className={css.childclass2}></div>
</div>
Component1 (Parent Component)
<Component2 classWrapper={css.class1} />
.class1{
.childclass2{
// the styles defined here are not reflected in the Component2
}
}
I'm trying to add a custom HTML attribute on a React component:
const Parent = () => (
<div className="parent">
<Child data-custom="foo" />
</div>
);
Where Child is another React component, but the attribute gets stripped on the output HTML. I'm aware that I could simply add the attribute on the Child root element, like so:
const Child = () => <div className="child" data-custom="foo" />
Or read the attribute in the Child component via props, but that's not what i'm looking since that would couple the attribute with the component, and I'm looking for a more contextual approach (the attribute would be used for test automation purposes).
Is there a clean way to do that in React?
I'm also considering writing a Babel plugin to add the attribute or prevent the stripping, but that would be another question.
Thanks!
React element doesn't necessarily correspond to DOM element that could have HTML attributes. React component can be rendered to multiple DOM elements or no elements at all.
If Child should be able to provide additional props or attributes to child DOM element, it should pass them explicitly:
const Child = props => <div className="child" {...props} />
This way data-custom="foo" will be passed to <div>.
For this, you can try this in your react script.
const MyCompo = () => {
return (
<div>
<p>HTML Code</p>
</div>
);
}
export default About;
Otherwise you can create class and then define your components and then export them.
import React from 'react';
import '../assets/css/style.css';
import '../assets/css/pure-min.css';
import '../assets/css/custom.css';
import 'font-awesome/css/font-awesome.min.css';
import $ from 'jquery';
class FirstScreen extends React.Component {
constructor(props) {
super(props);
this.handleLoad = this.handleLoad.bind(this);
}
componentDidMount() {
window.addEventListener('load', this.handleLoad);
}
handleLoad() {
}
render() {
return <div>HTML Code</div>;
}
}
export default FirstScreen;
You could use the below syntax
const Parent = () => (
<div className="parent">
<Child data-custom="foo"/>
</div>
);
const Child = ({...props}) => (<div className="child" {...props} />)