Passing components into another in react - reactjs

I have an app with a number of components. One of the components I need be to able to pass different variations of another two components into, based on a layout. I believe it can be passed in like a data attribute, but I'm unsure of the exact syntax to push the other components in.
Given two components <List /> and <Box /> which are currently in another component being imported into my main App.js file as such:
export const CallOut = () => {
return(
<div style={styles.sectionInner}>
<List />
<BoxRight/>
</div>
)
};
where <CallOut /> is being imported into App.js, I'd like to pass those two components into the <CallOut /> component.
What is the correct syntax to pass those two in and have them placed in the same spot they're currently in within the CallOut component?
I believe it should be something similar to
<CallOut param={List} param={BoxRight} />
but I know this isn't right.

You can use capital names for props, and use these to instantiate react components like this:
export const CallOut = ({List, Box}) => (
<div style={styles.sectionInner}>
<List/>
<Box/>
</div>
);
List and Box are the properties of this component. You can instantiate it like this:
<CallOut List={SomeComponent} Box={SomeOtherComponent}/>

I don't know if we're on the same page but maybe you're looking for children property ?
So your component will look like that:
export const CallOut = ({children}) => (
<div style={styles.sectionInner}>
{children}
</div>
);
And usage:
<CallOut >
<List/>
<Box/>
</CallOut>
You can pass any component as CallOut child or even do some filtering using children API
It's common usage when components don’t know their children ahead of time and it's used just for some kind of boxing/wrapping.

Related

How to return multiple times same component but with independant state?

Hi guys in react i want to do something like render 2 times a component in same render function like this
const Main()=>{
const [names, setNames] = useState([]);
const [selected, setSelected] = useState(-1);
return(
<Component1 name={names[selected].name}
setName={setNames}/>
<Component1 name={names[selected].name}
setName={setNames}/>
)
}
This where i passed setNames from Main() to Component1 to handle state
and pass names from Main() then map it in select of Component1
<StyledSelect
ml="10px"
onChange={(e) => {
setName(e.target.value);
value={name}>
{names.map(({ name}) => {
return (
<option key={name} value={name}>
{name}
</option>
);
})}
my component has an html select that has names in it, when i choose one it trigger a it in database and retrieve name data (age, location), the problem is when i select name on my second Component1, it will also select the same name and retrieve same name data on my first Component1, and i want them to be independent. How ?
I tried to put key like that
return(
<Component1 key="compare" name={name}/>
<Component1 key="compared" name={name}/>
)
but nothing changes
Thanks
This question is worded incorrectly (this has nothing to do with state and everything to do with props and how React renders) and is missing information, but here are a few pieces of information that might help:
Keys don't change anything on the front-end; they are a tool React uses to improve performance on the back-end. Click here to read the docs for more information on keys and how React uses them.
React components are JavaScript functions and can therefore only return 1 thing. The code sample you shared would not work in React (or JavaScript). In order to return multiple items, it is possible to wrap them in an array or a React Fragment. Consider this example:
render() {
return (
<React.Fragment>
<ChildA />
<ChildB />
<ChildC />
</React.Fragment>
);
}
If you want to make the dropdowns different in appearance and/or functionality, the name prop will need to be different. Right now, both instances of Component1 are being given the same name property, which is why they probably look and behave identically.
(i would like can comment but i can't)
i am not sure (i must see the complete code) but i think that:
return(
<Component1 key="compare" name={name}/>
<Component1 key="compared" name={name}/>
)
must be
return(
<Component1 key="compare" name={name1}/>
<Component1 key="compared" name={name2}/>
)
this way they don't share the same variable
Where is it that you're making the call and setting the name? Since you're passing the same prop name to both of them they will be the same.
Either you set name inside Component1 itself or you make a different state for each Component1.

Render Map child from outside MapContainer

I would like to render a child inside <MapContainer> from outside the initial MapContainer. Is this possible somehow?
In react-leaflet-v3 I render a lot of items on the map by passing the map object via a reference. But for my current situation I wold like to render a react button on top of the map based on routing.
One way of doing this is to add nest <Route />. inside the MapContainer. This however is not ideal because of the scattered route behaviour...
Is it possible in another way?
I used the portal way to solve my problem:
In my map-container, this is happening:
const [control, setControl] = useState(null);
const handleRef = useCallback((instance) => setControl(instance), [
setControl,
]);
...
<MapContainer ...>
...
<div className="mapcontrol-top-left" ref={handleRef}></div>
</MapContainer>
In a totally different component, where conditionally I want to show something on the Map, I do this (using Material-UI Portal & Fab component):
<Portal container={props.control}>
<Fab size="medium">
<EditIcon />
</Fab>
</Portal>
The material-ui Portal component is easy to use and adds convenience, but a native React Portal will also do the trick...

How is it possible to make one component stand out from other same component in React

I was creating React project and I have component which is used in several places in the project. The question is how is it possible to make one certain different from other instances of that component in terms of css styling?
For achieving that you have to accept the styles of the component as props. And each time you use the component pass the desired style to each instance.
For example
const PopupHeader = ({ title, onClose, classes }) => (
<div className={classNames(styles.head, classes.header)}>
<span className={styles.headText}>
{title}
</span>
</div>
);
Here the PopupHeader component is receiving classes as props which is actually an object of styles passed from parent component, which is used in the child component.
Hope it helps.
You can use contextAPI for sending the styles in all components
<ParentComponent>
<Style.Provider value={{ style: "background: "white .. or something" }}>
{this.props.children}
</Style.Provider>
</ParentComponent>
You can send the styles in all child components

Material UI. Show different components depending on breakpoints (SSR)

On small devices (phones) I want to show <Foo/> component and on large (desktops) <Bar/>, like this
function MyComp (props) {
if (isMobile)
return <Foo/>
else
return <Bar/>
}
}
I could find only 2 possible ways to implement it in Material UI :
Using Hidden component
Using withWidth HOC
Option with HOC seemed to me more correct in this case, but apparently it doesn't work correctly with SSR (but Hidden does).
So is it OK in terms of best practices to use two Hidden elems? Like this:
function MyComp (props) {
return (
<>
<Hidden mdUp implementation="css">
<Foo/>
</Hiddne>
<Hidden smDown implementation="css">
<Bar/>
</Hidden>
</>
)
}
There is no problem in using <Hidden /> like that, it just adds a <div> with the necessary CSS to show or not your component. A better approach though would be to add a CSS class directly to your <Foo /> and <Bar /> components, to avoid extra <div> in your page, like this:
function MyComp (props) {
return (
<>
<Foo className={props.classes.foo} />
<Bar className={props.classes.bar} />
</>
)
}
The implementation="css" is necessary in SSR setups because the JS implementation may "flash" the component on the page, then remove it when JS has loaded. The downside of the CSS implementation is that the element is kept in the DOM.
PS: withWidth will be deprecated.

ReactJs: render a collection of dynamic components

I'm rather new to react.js and I wonder if it's possible to render a collection of different components with React?
For example I have a ContainerComponent class with a property childComponents which I want to use like this:
var childComponents = [];
childComponents.push(<TextComponent text={this.props.text} />);
childComponents.push(<PictureComponent src={this.props.image} />);
return (
<ContainerComponent
title={this.props.title}
innerComponents={childComponents} />
)
So the problem is that I can't call child components' render function in loop to generate single output of all children. How could render method of ContainerComponent look like?
Thanks!
Place all the components like you would normally do:
render() {
return (
<div>
{this.props.innerComponents}
</div>
);
}
Normally, the following code should work fine for your needs:
<ContainerComponent
title={this.props.title}
>
<TextComponent text={this.props.text} />
<PictureComponent text={this.props.image} />
</ContainerComponent>

Resources