How to pass information to nested components in react? - javascript

Say I have
<component1>
<component2>
<component3>
<component4>
(where component1 has a child component2, component2 has a child component3, component3 has a child component4 )
and say I want to pass something from component1 into component4 . Do I need to pass props down the chain? so component1 -> component2 -> component3 -> component4
?
Please note:
these components are not in the same file. so in component1.js I refer to <component2> and in component2.js I refer to <component3> etc.

You have 2 main options here:
Pass down the props.
Use the context API
With props you also got 2 main options:
You can pass the props implicit
<Parent>
<ChildOne {...props}>
<ChildTwo {...props}>
</ChildTwo>
</ChildOne>
</Parent>
Running snippet for implicit props:
const ChildTwo = props => (
<div>{`Child two says: ${props.myProp}`}</div>
);
const ChildOne = props => (
<div>
<ChildTwo {...props} />
</div>
);
const Parent = props => (
<div>
<ChildOne {...props} />
</div>
);
ReactDOM.render(<Parent myProp="hi there" />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Or do it explicit
<Parent>
<ChildOne propOne={propOne}>
<ChildTwo propOne={propOne}>
</ChildTwo>
</ChildOne>
</Parent>
Running snippet for explicit props:
const ChildTwo = (props) => (
<div>{`Child two says: ${props.myProp}`}</div>
);
const ChildOne = props => (
<div>
<ChildTwo myProp={props.myProp} />
</div>
);
const Parent = props => (
<div>
<ChildOne myProp={props.myProp} />
</div>
);
ReactDOM.render(<Parent myProp="hi there" />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
As for the context API, you can skip levels and "grab" props from grandparents.
This is what react-redux does behind the scenes.
Running example of the context API:
const ChildTwo = (props, context) => (
<div>{`Child two says: ${context.myProp}`}</div>
);
ChildTwo.contextTypes = { myProp: React.PropTypes.string }
const ChildOne = props => (
<div>
<ChildTwo />
</div>
);
class Parent extends React.Component {
getChildContext() {
const { myProp } = this.props;
return { myProp };
}
render() {
return (
<div>
<ChildOne />
</div>
);
}
}
Parent.childContextTypes = {
myProp: React.PropTypes.string
};
ReactDOM.render(<Parent myProp="hi there" />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Note that this example is using react v15, which the syntax for React.PropTypes is changed, Since react v16 PropTypes is no longer part of the react library and it was extracted to another library prop-types.
Also Note, that the docs advise against the usage of the context API:
If you aren’t an experienced React developer, don’t use context. There
is usually a better way to implement functionality just using props
and state.

You can use React's inbuilt Context API, although I wouldn't suggest you rely too much on this because this either could get deprecated or be made into a full stable feature. As of now Facebook warns users with some points in their docs WARNING. Without that hiccup, the API is just wonderful and helps maintain neat code without having to send props all the way to the intended descendant.
CONTEXT API
COMPONENT 1
class Component1 extends React.Component {
getChildContext() {
return {
yourProp: "someValue" // you can also add a function like yourProp: someFunc
};
}
render() {
<Component2 />
}
}
Component1.childContextTypes = {
yourProp: PropTypes.string
};
COMPONENT 2
class Component2 extends React.Component {
render() {
return (
<Component3 />
);
}
}
COMPONENT 3
class Component3 extends React.Component {
render() {
return (
<Component4 />
);
}
}
COMPONENT4
class Component4 extends React.Component {
render() {
return (
<div>
{this.context.yourProp}
</div>
);
}
}
Component4.contextTypes = {
yourProp: PropTypes.string
};
There are quite many strategies if you don't choose to use this.
REDUX
EVENT EMITTER
PASSING PROPS ALL THE WAY TO THE DESCENDANT

Yes with using just React you would need to pass down props through each component, even if the component doesn't use that prop. So in your example control2 & control3 don't care about the prop but need to pass it down. Below is what you would need to do.
<Control1 test={this.state.test}>
<Control2 test={this.props.test}>
<Control3 test={this.props.test}>
<Control4 test={this.props.test} />
</Control3>
</Control2>
</Control1>
This can get cumbersome so this is a case where redux can help.

Related

React context in MPA (one context for different apps)

I'm rendering several react "snippets" on one page
ReactDOM.render(<MainNavSearchApp />, document.getElementById('main-nav-search-app'));
ReactDOM.render(<NavSearchBrandsApp />, document.getElementById('main-nav-search-brands-app'));
and want to use one context for them
class MainNavSearchApp extends React.Component {
render() {
return (
<div>
<NavSearchContextProvider>
<MainNavSearch />
</NavSearchContextProvider>
</div>
);
}
}
export default MainNavSearchApp;
class NavSearchBrandsApp extends React.Component {
render() {
return (
<div>
<NavSearchContextProvider>
<NavSearchBrands />
</NavSearchContextProvider>
</div>
);
}
}
export default NavSearchBrandsApp;
but if I update the context in on of the apps, it does not get updated in the other. As I understand, React creates two "clone" independent contexts. Can multiple instances use the same context?
Yes you can, as data in React flows down, they must have a common parent in order to share same context data.
This is commonly called a “top-down” or “unidirectional” data flow. Any state is always owned by some specific component, and any data or UI derived from that state can only affect components “below” them in the tree.
Therefore, the common parent should use ReactDOM.createPortal, and render the provider, while other components will be his children.
<body>
<div id="root"></div>
<div id="app1"></div>
<div id="app2"></div>
</body>
// Common parent - MUST
function Root() {
return (
<Context.Provider value={42}>
{ReactDOM.createPortal(<App1 />, document.getElementById("app1"))}
{ReactDOM.createPortal(<App2 />, document.getElementById("app2"))}
</Context.Provider>
);
}
// MainNavSearchApp
function App1() {
const val = React.useContext(Context);
return <>App1: {val}</>;
}
// NavSearchBrandsApp
function App2() {
const val = React.useContext(Context);
return <>App2: {val}</>;
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Root />, rootElement);

Relation between components

I have two stateful components:Grid and Item.Item is rendering by Grid and have props which reference to method (handler) defined in Grid <Item example={this.props.inGridHandler} />
Ok. But what if I have third stateful component let's name it Handy and I want that inGridHandler is defined not in Grid component as before but in Handy. How to achieve this with preserving all this structure ?
class Grid extends Component{
ingridHandler=()=>{
console.log('I want to be defined in Handy Component, not here');
}
Render(){
Return(
`<Item example={this.inGridHandler} />`
);
}
};
export default Grid;
class Handy extends Component{
inGridHandlerWantToBeDefinedHere=()=>{
console.log("I want to be defined here and pass to Grid component as props of Item component which is rendered there'
}
render(){
return(
)
}
}
Here is what you want if I understand you right. This is a very simple process. You are just passing the props all the way down. But, as I try to explain in my comments in the future you should think better approaches if you don't want to pass the props like this.
class Handy extends React.Component {
inGridHandler = () => {
console.log("ingridhandler");
};
render() {
return <Grid inGridHandler={this.inGridHandler} />;
}
}
class Grid extends React.Component {
render() {
return <Item inGridHandler={this.props.inGridHandler} />;
}
}
const Item = props => (
<button onClick={props.inGridHandler}>Click me and look the console.</button>
);
ReactDOM.render(
<Handy />,
document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

How to share state between child component (siblings) in ReactJS?

I would like to pass state to a sibling or even a grandparent whatever.
I have 3 components. Inside Header, I have a button with an onClick function to toggle a Dropdown Menu inside Navigation. And by the way, I would like to pass the same state to AnotherComponent.
How to pass state (such as isDropdownOpened) from Header to Navigation and AnotherComponent?
<div>
<Header />
<Navigation />
<div>
<div>
<div>
<AnotherComponent />
</div>
</div>
</div>
</div>
You have different approaches to address this situation.
Keep the state in the top component and pass it to children through props
Use a state container to keep and share your application state among components (e.g. https://redux.js.org/)
Use the new React Context feature. Context provides a way to pass data through the component tree without having to pass props down manually at every level.
That's the exact reason why "React Hooks" have been developed (and hyped by the community 😉), but don't use them yet in production, they are still in early development (alpha) and their specification/implementation might be changed!
You problem can be solved using the awesome “React Context“ API which allows to pass data to components no matter how deep they are nested in the tree.
To get to know to context read the extensive documentation linked above. I'll only explain a small and quick example here:
Create a context component and export the consumer
App.jsx
import React from "react";
// The initial value can be anything, e.g. primitives, object, function,
// components, whatever...
// Note that this is not required, but prevebents errors and can be used as
// fallback value.
const MyContext = React.createContext("anything");
// This component is the so called "consumer" that'll provide the values passed
// to the context component. This is not necessary, but simplifies the usage and
// hides the underlying implementation.
const MyContextConsumer = MyContext.Consumer;
const someData = { title: "Hello World" };
const App = ({ children }) => (
<MyContext.Provider value={someData}>{children}</MyContext.Provider>
);
export { MyContextConsumer };
export default App;
Import the created consumer in any component and use the provided value
AnotherComponent.jsx
import React from "react";
import { MyContextConsumer } from "./App";
const AnotherComponent = () => (
<div>
<MyContextConsumer>{({ title }) => <h1>{title}</h1>}</MyContextConsumer>
</div>
);
export default AnotherComponent;
Render the app with both context components
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import AnotherComponent from "./AnotherComponent";
const Root = () => (
<App>
<AnotherComponent />
</App>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<Root />, rootElement);
The component will render a level 1 heading with the "Hello World" text.
How to pass state (such as isDropdownOpened) from Header to Navigation and AnotherComponent, please ?
You hold the state in an ancestor of Header and pass that state to Haeader, Navigation, and AnotherComponent as props. See State and Lifecycle and Lifting State Up in the documentation.
Example:
const Header = props => (
<div>
<span>Header: </span>
{props.isDropdownOpened ? "Open" : "Closed"}
</div>
);
const Navigation = props => (
<div>
<span>Navigation: </span>
{props.isDropdownOpened ? "Open" : "Closed"}
</div>
);
const AnotherComponent = props => (
<div>
<span>AnotherComponent: </span>
{props.isDropdownOpened ? "Open" : "Closed"}
</div>
);
class Wrapper extends React.Component {
constructor(props) {
super(props);
this.state = {
isDropdownOpened: false
};
}
componentDidMount() {
setInterval(() => {
this.setState(({isDropdownOpened}) => {
isDropdownOpened = !isDropdownOpened;
return {isDropdownOpened};
});
}, 1200);
}
render() {
const {isDropdownOpened} = this.state;
return (
<div>
<Header isDropdownOpened={isDropdownOpened} />
<Navigation isDropdownOpened={isDropdownOpened} />
<div>
<div>
<div>
<AnotherComponent isDropdownOpened={isDropdownOpened} />
</div>
</div>
</div>
</div>
);
}
}
ReactDOM.render(
<Wrapper />,
document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
There are some other options, which Arnaud usefully provides in his answer.
Like how TJ Said, use the state of the parent component. That way one state is shared by all the sub components, which is what you wanted I presume.
class ExampleParentComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
isDropdownOpened: false
}
}
toggleDropdown() {
this.setState({
isDropdownOpened: !isDropdownOpened
});
}
render() {
return (
<div>
<Header open={isDropdownOpened} toggleDropdown={ this.toggleDropdown }/>
<Navigation open={ isDropdownOpened}/>
<div>
<div>
<div>
<AnotherComponent open={ isDropdownOpened} />
</div>
</div>
</div>
</div>
);
}
class Header extends React.Component {
render() {
return (
<div>
<button onClick={ this.props.toggleDropdown }>TOGGLE ME</button>
{ isDropdownOpened && (
<h1> DROPPED </h1>
}
</div>
);
}
}
You can only use this.state.variableName to access
<ChildComponent data={this.state.name} />
And to pass functions
<ChildComponent data={this.HandleChange} />
First Send the data from the first child to the common parent using callback
function and then send that received data (stored in state in parent component)
to the second child as props.
you can also read this article - https://www.pluralsight.com/guides/react-communicating-between-components

Functions are not valid as a React child. This may happen if you return a Component instead of from render

I have written a Higher Order Component:
import React from 'react';
const NewHOC = (PassedComponent) => {
return class extends React.Component {
render(){
return (
<div>
<PassedComponent {...this.props}/>
</div>
)
}
}
}
export default NewHOC;
I am using the above in my App.js:
import React from 'react';
import Movie from './movie/Movie';
import MyHOC from './hoc/MyHOC';
import NewHOC from './hoc/NewHOC';
export default class App extends React.Component {
render() {
return (
<div>
Hello From React!!
<NewHOC>
<Movie name="Blade Runner"></Movie>
</NewHOC>
</div>
);
}
}
But, the warning I am getting is:
Warning: Functions are not valid as a React child. This may happen if
you return a Component instead of <Component /> from render. Or maybe
you meant to call this function rather than return it.
in NewHOC (created by App)
in div (created by App)
in App
The Movie.js file is:
import React from "react";
export default class Movie extends React.Component{
render() {
return <div>
Hello from Movie {this.props.name}
{this.props.children}</div>
}
}
What am I doing wrong?
I did encounter this error too because I didn't use the correct snytax at routing. This was in my App.js under the <Routes> section:
False:
<Route path="/movies/list" exact element={ MoviesList } />
Correct:
<Route path="/movies/list" exact element={ <MoviesList/> } />
So now the MoviesList is recognized as a component.
You are using it as a regular component, but it's actually a function that returns a component.
Try doing something like this:
const NewComponent = NewHOC(Movie)
And you will use it like this:
<NewComponent someProp="someValue" />
Here is a running example:
const NewHOC = (PassedComponent) => {
return class extends React.Component {
render() {
return (
<div>
<PassedComponent {...this.props} />
</div>
)
}
}
}
const Movie = ({name}) => <div>{name}</div>
const NewComponent = NewHOC(Movie);
function App() {
return (
<div>
<NewComponent name="Kill Bill" />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"/>
So basically NewHOC is just a function that accepts a component and returns a new component that renders the component passed in. We usually use this pattern to enhance components and share logic or data.
You can read about HOCS in the docs and I also recommend reading about the difference between react elements and components
I wrote an article about the different ways and patterns of sharing logic in react.
In my case i forgot to add the () after the function name inside the render function of a react component
public render() {
let ctrl = (
<>
<div className="aaa">
{this.renderView}
</div>
</>
);
return ctrl;
};
private renderView() : JSX.Element {
// some html
};
Changing the render method, as it states in the error message to
<div className="aaa">
{this.renderView()}
</div>
fixed the problem
I encountered this error while following the instructions here: https://reactjs.org/docs/add-react-to-a-website.html
Here is what I had:
ReactDOM.render(Header, headerContainer);
It should be:
ReactDOM.render(React.createElement(Header), headerContainer);
I had this error too. The problem was how to call the function.
Wrong Code:
const Component = () => {
const id = ({match}) => <h2>Test1: {match.params.id}</h2>
return <h1>{id}</h1>;
};
Whereas id is a function, So:
Correct code:
return <h1>{id()}</h1>;
Adding to sagiv's answer, we should create the parent component in such a way that it can consist all children components rather than returning the child components in the way you were trying to return.
Try to intentiate the parent component and pass the props inside it so that all children can use it like below
const NewComponent = NewHOC(Movie);
Here NewHOC is the parent component and all its child are going to use movie as props.
But any way, you guyd6 have solved a problem for new react developers as this might be a problem that can come too and here is where they can find the solution for that.
I was able to resolve this by using my calling my high order component before exporting the class component. My problem was specifically using react-i18next and its withTranslation method, but here was the solution:
export default withTranslation()(Header);
And then I was able to call the class Component as originally I had hoped:
<Header someProp={someValue} />
it also happens when you call a function from jsx directly rather than in an event. like
it will show the error if you write like
<h1>{this.myFunc}<h2>
it will go if you write:
<h1 onClick={this.myFunc}>Hit Me</h1>
I was getting this from webpack lazy loading like this
import Loader from 'some-loader-component';
const WishlistPageComponent = loadable(() => import(/* webpackChunkName: 'WishlistPage' */'../components/WishlistView/WishlistPage'), {
fallback: Loader, // warning
});
render() {
return <WishlistPageComponent />;
}
// changed to this then it's suddenly fine
const WishlistPageComponent = loadable(() => import(/* webpackChunkName: 'WishlistPage' */'../components/WishlistView/WishlistPage'), {
fallback: '', // all good
});
In my case, I was transport class component from parent and use it inside as a prop var, using typescript and Formik, and run well like this:
Parent 1
import Parent2 from './../components/Parent2/parent2'
import Parent3 from './../components/Parent3/parent3'
export default class Parent1 extends React.Component {
render(){
<React.Fragment>
<Parent2 componentToFormik={Parent3} />
</React.Fragment>
}
}
Parent 2
export default class Parent2 extends React.Component{
render(){
const { componentToFormik } = this.props
return(
<Formik
render={(formikProps) => {
return(
<React.fragment>
{(new componentToFormik(formikProps)).render()}
</React.fragment>
)
}}
/>
)
}
}
What would be wrong with doing;
<div className="" key={index}>
{i.title}
</div>
[/*Use IIFE */]
{(function () {
if (child.children && child.children.length !== 0) {
let menu = createMenu(child.children);
console.log("nested menu", menu);
return menu;
}
})()}
In my case I forgot to remove this part '() =>'. Stupid ctrl+c+v mistake.
const Account = () => ({ name }) => {
So it should be like this:
const Account = ({ name }) => {
In my case
<Link key={uuid()} to="#" className="tag">
{post.department_name.toString}
</Link>
changed with
<Link key={uuid()} to="#" className="tag">
{post.department_name.toString()}
</Link>
You should use
const FunctionName = function (){
return (
`<div>
hello world
<div/>
`
)
};
if you use Es6 shorthand function it will give error use regular old javascript function.

How to pass in a react component into another react component to transclude the first component's content?

Is there a way to pass one component into another react component? I want to create a model react component and pass in another react component in order to transclude that content.
Edit: Here is a reactJS codepen illustrating what I'm trying to do. http://codepen.io/aallbrig/pen/bEhjo
HTML
<div id="my-component">
<p>Hi!</p>
</div>
ReactJS
/**#jsx React.DOM*/
var BasicTransclusion = React.createClass({
render: function() {
// Below 'Added title' should be the child content of <p>Hi!</p>
return (
<div>
<p> Added title </p>
{this.props.children}
</div>
)
}
});
React.renderComponent(BasicTransclusion(), document.getElementById('my-component'));
You can use this.props.children to render whatever children the component contains:
const Wrap = ({ children }) => <div>{children}</div>
export default () => <Wrap><h1>Hello word</h1></Wrap>
Note I provided a more in-depth answer here
Runtime wrapper:
It's the most idiomatic way.
const Wrapper = ({children}) => (
<div>
<div>header</div>
<div>{children}</div>
<div>footer</div>
</div>
);
const App = () => <div>Hello</div>;
const WrappedApp = () => (
<Wrapper>
<App/>
</Wrapper>
);
Note that children is a "special prop" in React, and the example above is syntactic sugar and is (almost) equivalent to <Wrapper children={<App/>}/>
Initialization wrapper / HOC
You can use an Higher Order Component (HOC). They have been added to the official doc recently.
// Signature may look fancy but it's just
// a function that takes a component and returns a new component
const wrapHOC = (WrappedComponent) => (props) => (
<div>
<div>header</div>
<div><WrappedComponent {...props}/></div>
<div>footer</div>
</div>
)
const App = () => <div>Hello</div>;
const WrappedApp = wrapHOC(App);
This can lead to (little) better performances because the wrapper component can short-circuit the rendering one step ahead with shouldComponentUpdate, while in the case of a runtime wrapper, the children prop is likely to always be a different ReactElement and cause re-renders even if your components extend PureComponent.
Notice that connect of Redux used to be a runtime wrapper but was changed to an HOC because it permits to avoid useless re-renders if you use the pure option (which is true by default)
You should never call an HOC during the render phase because creating React components can be expensive. You should rather call these wrappers at initialization.
Note that when using functional components like above, the HOC version do not provide any useful optimisation because stateless functional components do not implement shouldComponentUpdate
More explanations here: https://stackoverflow.com/a/31564812/82609
const ParentComponent = (props) => {
return(
{props.childComponent}
//...additional JSX...
)
}
//import component
import MyComponent from //...where ever
//place in var
const myComponent = <MyComponent />
//pass as prop
<ParentComponent childComponent={myComponent} />
You can pass it as a normal prop: foo={<ComponentOne />}
For example:
const ComponentOne = () => <div>Hello world!</div>
const ComponentTwo = () => (
<div>
<div>Hola el mundo!</div>
<ComponentThree foo={<ComponentOne />} />
</div>
)
const ComponentThree = ({ foo }) => <div>{foo}</div>
Facebook recommends stateless component usage
Source: https://web.archive.org/web/20160608001717/http://facebook.github.io/react/docs/reusable-components.html
In an ideal world, most of your components would be stateless
functions because in the future we’ll also be able to make performance
optimizations specific to these components by avoiding unnecessary
checks and memory allocations. This is the recommended pattern, when
possible.
function Label(props){
return <span>{props.label}</span>;
}
function Hello(props){
return <div>{props.label}{props.name}</div>;
}
var hello = Hello({name:"Joe", label:Label({label:"I am "})});
ReactDOM.render(hello,mountNode);
i prefer using React built-in API:
import React, {cloneElement, Component} from "react";
import PropTypes from "prop-types";
export class Test extends Component {
render() {
const {children, wrapper} = this.props;
return (
cloneElement(wrapper, {
...wrapper.props,
children
})
);
}
}
Test.propTypes = {
wrapper: PropTypes.element,
// ... other props
};
Test.defaultProps = {
wrapper: <div/>,
// ... other props
};
then you can replace the wrapper div with what ever you want:
<Test wrapper={<span className="LOL"/>}>
<div>child1</div>
<div>child2</div>
</Test>
You can pass in a component via. the props and render it with interpolation.
var DivWrapper = React.createClass({
render: function() {
return <div>{ this.props.child }</div>;
}
});
You would then pass in a prop called child, which would be a React component.
Late to the game, but here's a powerful HOC pattern for overriding a component by providing it as a prop. It's simple and elegant.
Suppose MyComponent renders a fictional A component but you want to allow for a custom override of A, in this example B, which wraps A in a <div>...</div> and also appends "!" to the text prop:
import A from 'fictional-tooltip';
const MyComponent = props => (
<props.A text="World">Hello</props.A>
);
MyComponent.defaultProps = { A };
const B = props => (
<div><A {...props} text={props.text + '!'}></div>
);
ReactDOM.render(<MyComponent A={B}/>);
Actually, your question is how to write a Higher Order Component (HOC). The main goal of using HOC is preventing copy-pasting. You can write your HOC as a purely functional component or as a class here is an example:
class Child extends Component {
render() {
return (
<div>
Child
</div>
);
}
}
If you want to write your parent component as a class-based component:
class Parent extends Component {
render() {
return (
<div>
{this.props.children}
</div>
);
}
}
If you want to write your parent as a functional component:
const Parent = props => {
return (
<div>
{props.children}
</div>
);
}
Here is an example of a parent List react component and whos props contain a react element. In this case, just a single Link react component is passed in (as seen in the dom render).
class Link extends React.Component {
constructor(props){
super(props);
}
render(){
return (
<div>
<p>{this.props.name}</p>
</div>
);
}
}
class List extends React.Component {
render(){
return(
<div>
{this.props.element}
{this.props.element}
</div>
);
}
}
ReactDOM.render(
<List element = {<Link name = "working"/>}/>,
document.getElementById('root')
);
Let's create a Wrapper Component:
export const Wrapper = (props) => {
return(<>
<Menu />
{props.children}
<Footer />
</>
)
}
You can now enclose your new into an existing structure.
You will enclose the Component in a Route for example:
<Route path="/" element={<Wrapper><ExampleComponent /></Wrapper>} />
You can pass your component as a prop and use the same way you would use a component.
function General(props) {
...
return (<props.substitute a={A} b={B} />);
}
function SpecificA(props) { ... }
function SpecificB(props) { ... }
<General substitute=SpecificA />
<General substitute=SpecificB />
you can pass your react component into another component and emit the function from child
import CustomerFilters;
parent:
const handleFilterChange = (value) => {
console.log(value)
}
<DataGrid
contentName="customer"
fetchFilterComponents = {<CustomerFilters onSelectFilter={handleFilterChange} />}
</DataGrid>
child:
CustomerFilters
return (
<select className="filters-dropdown" onChange={onSelectFilter}>
<option>Select Filter</option>
{customerFilterOptions?.map((filter: any) => {
return <option value={filter.value}>{filter.name}</option>;
})}
</select>
)

Categories

Resources