React component position styling best practice - reactjs

I wanted to get an understanding on what people would consider best practice for layout of their react components, and if the layout styling should or should not be tightly coupled within the component itself.
Say I have a custom component that will be reused many times within the application, there may be times when I was them to be stacked Vertically down the page, with margin-bottom:20px;, whereas there may be cases I would like them spread out horizontally across the page with margin-right:20px;
It doesn't feel right if I were to have margins, or other layout attributes tightly coupled with the component? I would have thought that I should be able to render by component in isolation, without it having positional styling coupled along with it?

If you're using the component multiple times in one layout then of course the margin is not part of your component but the component that contains it.
You can use different methods to achieve your desired margin, for instance you have the css grid gap that defines just that.
However if you are using flex, you might have to pass the desired margin down to the component. So having something like this inside the component would be helpful in that case:
<div id="container" style={[styles.container, this.props.margin]}>
That way you can give it a default margin in the container style while still allowing yourself to pass a dynamic value through props when using in different places.

You could have a prop that defines the type of the component, let's say, a type prop. And you can apply the classes based on the type prop you receive with a default type.
static propTypes = { type: PropTypes.oneOf(['info', 'warning', 'error']) };
default propTypes = { type: 'info' };
and the render would look like this :
<div className={styles[this.props.type]}>content</div>
Or you can just have a single way your component look and add a className prop and/or just pass your custom styles as inline styles.
<MyComponent style={{ marginBottom: '30px' }} className="CustomStyleInClass" type="error" />
You could either use one, two or all. It depends on the component and the flexibility you need.

Related

React Transition Group: What is the purpose of TransitionGroup?

I'm looking to use the React Transition Group library to animate some stuff in my React page. According to those docs, the TransitionGroup component does the following:
The <TransitionGroup> component manages a set of transition components
( and <CSSTransition>) in a list. Like with the transition
components, <TransitionGroup> is a state machine for managing the
mounting and unmounting of components over time.
Consider the example below. As items are removed or added to the
TodoList the in prop is toggled automatically by the
<TransitionGroup>.
I'm not really sure what that means or why it's important.
Also, when I modify the example code that they embed on the documentation page so that the <TransitionGroup> tags are replaced with <ul> tags everything seems to work just fine (I can remove todo items by clicking on them, I can add new todo items).
Why is <TransitionGroup> component necessary? What does it do? (And why do things appear to work just fine when I replace it with an unordered list?)
React Transition Group has some advantages over typical css animations.These are some points that are coming to my mind.
Its uses binding to change classes for a components. eg: enter, appear, enter-active, appear-active, exit, exit-active etc are all part of animation classes. This make it really interactive interms of rich animations which you can not achive otherwise.
It has advatage to unmount your component using javascript, once animation is done. So basically no extra load on your front end.
It gives your freedom to define animations which ever way you like. Either css classes or defineing your own styles with in js file.
It gives you various type of animation options. Eg: Switch Transitions, Transition Groups, CssTransitions etc.
I would suggest to keep experimenting with typical css animations and react transition group and come to your own conclusion.

Can I wrap a custom component around a regular component in react native

So I have a component that returns a button with some custom text and an icon. I'm pulling the icons from expo vector icons and so to use the icons I need to write something like:
<Icon_Name name"name"......>
I want to wrap my custom component around an icon or any other component, so then I can use various different icons within that component.
So I want my code to basically be:
<Custom_Component>
<IconOrSomeOtherComponent />
</Custom_Component>
I want to somehow call that icon component within my custom component. Is this possible?
I know that I can pass in variables into a custom component like:
<Custom_Component someVariable="some variable" />
and then use "someVariable" within my the function of the component, but I was hoping to find a solution where I can just wrap a component and call the "wrapped" component inside the function of my "Custom_Component".
I'm using functional components by the way, not class components.

What is best way to avoid excessive nested components when using antd with React?

It looks like antd (https://ant.design) is generating an alarming amount of nesting to achieve its purpose. Maybe I'm wrong, but I feel there must be a better way.
For instance, I added colored text, like so:
<Text type="danger">Some words</Text>
At the DOM, it looks as expected:
<span class="ant-typography ant-typography-danger">Some words</span>
But when inspecting with react-tools, it looks bloated and doubled:
("...>" = omitted attributes)
<Text type="danger">
<withConfigConsumer(Base) ...>
<Context.consumer>
<Base ...>
<LocalReceiver ...>
<ReactResizeObserver ...>
<Typography ...>
<Content.consumer>
<span ...>
"Some words"
...
</Text>
<Context.consumer>
<Base ...>
<LocalReceiver ...>
<ReactResizeObserver ...>
<Typography ...>
<Content.consumer>
<span ...>
"Some words"
...
</Context.consumer>
Admittedly, I don't have enough experience with React. But isn't this excessive? Why is it doubled? And most of all: how can I use antd and avoid this?
You can't avoid this when using antd as this is a React design pattern their team decided to use. Those wrapper components are HOCs - higher-order components and their purpose is to apply/reuse some logic on their child components.
For example, in their GitHub repo, you can clearly see that Text, Title and Paragraph are simply the same Typography component whose inner text gets styled differently depending on if its passed a Text, Title or a Paragraph prop. This is to ensure extensibility: if they decide to create a Quote component, they will simply add a Quote entry to the Typography component, and define Quote styling that would possibly include italic text. The wrapper Typography component would then pass down this new italicized style to its child component - the inner text.
As for ReactResizeObserver, many Ant Design components require to have some kind of onResize event listener attached to themselves in order to be responsive - to change their size or structure based on the screen width. Instead of defining the same onResize listener and handler on every component that needs this functionality, they have created a single HOC that can wrap any component under the hood and allow it to be responsive.
You really shouldn't care about this, as this is common practice with many popular libraries like React Router or Redux.

Office Fabric UI I[component]StyleProp vs I[component]Styles interface use

In the Office Fabric UI documentation every component has two interfaces, for example
https://developer.microsoft.com/en-us/fabric#/components/nav
has
INavStyleProps interface
and
INavStyles interface
a component implementing INavStyleProps can take in any of the listed props to customize style, for example
I am wondering if there is any way to interact with INavStyles classes exposed through the documentation; essentially what does implementing the INavStyles interface guarantee to the consumer of the component, other than the listed classes and styles are implemented. Is there a way to override, customize, or otherwise interact with the classes exposed through this interface similar to how we can use props to interact with components implementing INavStylesProps.
Here is link showing the use of both interfaces for Nav. It's a how we give to Nav the default styles.
In order to override the default styles for any INavStyles area, you can use the styles prop and pass to it a styleFunctionOrObject. As you can see from the first link provided, INavStyleProps are used to pass some values to be used in the styling of the parts of the Nav or booleans to have some conditional styling. Also, that is how we pass the theme to the styles.
A style function you can pass to styles prop would look exactly as the one we use to provide the default styles minus the getGloballClassNames. Also if you want to style just one area the return type should be Partial<INavStyles> as all areas are required and it will complain if you don't provides styles for all of them.
Let me know if this cleared the confusion on how to make use of both interfaces.

How to check if the parent component is a specific component?

I'm pretty new to ReactJS, but I'm slowly getting behind it.
I want to create a smart component, it should detect if it is "inside" another component and render differently then.
Example:
<Menu>
<Item />
</Menu>
Here, the item component should render as an anchor.
If used inside any other component or a div, it should simply render as a div as well.
Is there an easy way to check, if a component is inside another component in React?
You could solve this by passing a prop, saying something about the context the component is being used in.
The simplest solution in your case would be to, whenever you use the item component in menu, you pass a prop.
render(){
<Menu>
<Item insideMenu={true} />
</Menu>
}
Then inside the render you have two different return statements (depending on the insideMenu-prop).
// Item.jsx
render() {
if(this.props.insideMenu)
return (whatever)
return (whateverElse)
}
Normally I wouldn't reccomend this though. Components, in my opinion, should be reuseable and generic if possible. In this case, I'd argue it would be better to have two components: Item and MenuItem. So then it would be
<Menu>
<MenuItem>
</Menu>
<AnythingElse>
<Item>
</AnythingElse>
Inside MenuItem, you may very well use the Item component as well, if they share the same behaviour. So in that case, MenuItem would render Item, as well as the extra behaviour required for the menu. Or simply wrap it inside an anchor-tag, if that's all there is to it.
Either solution works, but the latter is (in my opinion) cleaner. Less surprises, easier to read, and less that can go wrong (no need to juggle props).

Resources