Research
Security News
Threat Actor Exposes Playbook for Exploiting npm to Build Blockchain-Powered Botnets
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
react-sizeme
Advanced tools
The react-sizeme package is a React higher-order component (HOC) that makes it easy to get the dimensions of a component. It provides a way to measure the size of a component and pass those dimensions as props to the component, enabling responsive design and dynamic rendering based on component size.
Basic Usage
This example demonstrates the basic usage of react-sizeme. The SizeMe HOC is used to wrap a component, and it injects the size (width and height) as props into the wrapped component.
```jsx
import React from 'react';
import { SizeMe } from 'react-sizeme';
const MyComponent = ({ size }) => (
<div>
{`Width: ${size.width}, Height: ${size.height}`}
</div>
);
const SizeAwareComponent = SizeMe({ monitorHeight: true })(MyComponent);
export default SizeAwareComponent;
```
Using with Functional Components
This example shows how to use react-sizeme with functional components. The SizeMe HOC wraps the functional component and provides the size as props.
```jsx
import React from 'react';
import { SizeMe } from 'react-sizeme';
const MyFunctionalComponent = ({ size }) => (
<div>
{`Width: ${size.width}, Height: ${size.height}`}
</div>
);
const SizeAwareFunctionalComponent = SizeMe({ monitorHeight: true })(MyFunctionalComponent);
export default SizeAwareFunctionalComponent;
```
Custom Configuration
This example demonstrates how to use custom configuration options with react-sizeme. The options include monitoring width and height, setting a refresh rate, and disabling the placeholder.
```jsx
import React from 'react';
import { SizeMe } from 'react-sizeme';
const MyComponent = ({ size }) => (
<div>
{`Width: ${size.width}, Height: ${size.height}`}
</div>
);
const SizeAwareComponent = SizeMe({
monitorWidth: true,
monitorHeight: true,
refreshRate: 100,
noPlaceholder: true
})(MyComponent);
export default SizeAwareComponent;
```
react-measure is a package that provides a higher-order component and a render prop component to measure the size of a component. It offers more flexibility with render props and supports more detailed measurements like margins and padding. Compared to react-sizeme, react-measure provides more granular control over what measurements are taken and how they are used.
react-resize-detector is a lightweight package that provides a higher-order component and a hook to detect resize events on a component. It is simpler and more focused on detecting resize events rather than providing detailed size measurements. Compared to react-sizeme, react-resize-detector is more lightweight and easier to use for simple resize detection.
react-use-measure is a hook-based package that provides a way to measure the size of a component using the ResizeObserver API. It is modern and hook-based, making it a good fit for functional components and hooks-based codebases. Compared to react-sizeme, react-use-measure is more modern and leverages the latest React features.
Make your React Components aware of their width and height
import sizeMe from 'react-sizeme'
function MyComponent({ size }) {
return (
<div>My width is {size.width}px</div>
)
}
export default sizeMe()(MyComponent)
onSize
callback alternative usagereact-component-queries
size
data refresh rateGive your Components the ability to have render logic based on their height/width/position. Responsive design on the Component level. This allows you to create highly reusable components that don't care about where they will be rendered.
Check out a working demo here: https://react-sizeme.now.sh
First install the library.
npm install react-sizeme
We provide you with a function called sizeMe
. You can import it like so:
import sizeMe from 'react-sizeme';
When using the sizeMe
function you first have to pass it a configuration object. The entire configuration object is optional, as is each of its properties (in which case the defaults would be used).
Here is a full specification of all the properties available to the configuration object, with the default values assigned:
const sizeMeConfig = {
// If true, then any changes to your Components rendered width will cause an
// recalculation of the "size" prop which will then be be passed into
// your Component.
monitorWidth: true,
// If true, then any changes to your Components rendered height will cause an
// recalculation of the "size" prop which will then be be passed into
// your Component.
monitorHeight: false,
// If true, then any changes to your Components position will cause an
// recalculation of the "size" prop which will then be be passed into
// your Component.
monitorPosition: false,
// The maximum frequency, in milliseconds, at which size changes should be
// recalculated when changes in your Component's rendered size are being
// detected. This should not be set to lower than 16.
refreshRate: 16,
// The mode in which refreshing should occur. Valid values are "debounce"
// and "throttle". "throttle" will eagerly measure your component and then
// wait for the refreshRate to pass before doing a new measurement on size
// changes. "debounce" will wait for a minimum of the refreshRate before
// it does a measurement check on your component. "debounce" can be useful
// in cases where your component is animated into the DOM.
// NOTE: When using "debounce" mode you may want to consider disabling the
// placeholder as this adds an extra delay in the rendering time of your
// component.
refreshMode: 'throttle',
// By default we render a "placeholder" component initially so we can try
// and "prefetch" the expected size for your component. This is to avoid
// any unnecessary deep tree renders. If you feel this is not an issue
// for your component case and you would like to get an eager render of
// your component then disable the placeholder using this config option.
noPlaceholder: false
}
When you execute the sizeMe
function it will return a Higher Order Component (HOC). You can use this Higher Order Component to decorate any of your existing Components with the size awareness ability. Each of the Components you decorate will then recieve a size
prop, which is an object of schema { width: ?number, height: ?number, position: ?{ left: number, top: number, right: number, bottom: number} }
- the numbers representing pixel values. Note that the values can be null until the first measurement has taken place, or based on your configuration. Here is a verbose example showing full usage of the API:
import sizeMe from 'react-sizeme';
class MyComponent extends Component {
render() {
const { width, height } = this.props.size;
return (
<div>My size is {width || -1}px x {height || -1}px</div>
);
}
}
// Create the config
const config = { monitorHeight: true };
// Call SizeMe with the config to get back the HOC.
const sizeMeHOC = sizeMe(config);
// Wrap your component with the HOC.
export default sizeMeHOC(MyComponent);
You could also express the above much more concisely:
import sizeMe from 'react-sizeme';
class MyComponent extends Component {
render() {
const { width, height } = this.props.size;
return (
<div>My size is {width}px x {height}px</div>
);
}
}
export default sizeMe({ monitorHeight: true })(MyComponent);
That's it. Its really useful for doing things like optionally loading a child component based on the available space.
Here is an full example of that in action:
import React, { PropTypes } from 'react';
import LargeChildComponent from './LargeChildComponent';
import SmallChildComponent from './SmallChildComponent';
import sizeMe from 'react-sizeme';
function MyComponent(props) {
const { width, height } = props.size;
const ToRenderChild = height > 600
? LargeChildComponent
: SmallChildComponent;
return (
<div>
<h1>My size is {width}x{height}</div>
<ToRenderChild />
</div>
);
}
MyComponent.propTypes = {
size: PropTypes.shape({
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
})
}
export default sizeMe({ monitorHeight: true })(MyComponent);
EXTRA POINTS! Combine the above with a code splitting API (e.g. Webpack's System.import) to avoid unnecessary code downloads for your clients. Zing!
Important things to remember
null
values for the respective dimension.refreshRate
is set very low. If you are using this library in a manner where you expect loads of active changes to your components dimensions you may need to tweak this value to avoid browser spamming.onSize
callback alternative usagereact-sizeme
has now been extended to allow you to use your size aware components in an alternative fashion - having their size data be passed to a given callback function, rather than passed down to your component via a prop. This can give a nice alternative level of control, allowing the parent component to act as the intelligent container making all the decisions based on the size data.
I would highlight that for now this is an experimental feature, and wouldn't recommend over-use of it unless you are brave or have desperate need of it. I'd like to gather some nice feedback from the community on how useful this is to them and what other considerations I should make around it's API.
Here is an example of it's usage.
Firstly, create a component you wish to know the size of:
import sizeMe from 'react-sizeme'
function Hello({ to }) {
// ❗️ NOTE: no size prop will be provided if onSize callback was provided.
return <div>Hello {to}!</div>
}
export default sizeMe()(Hello)
Now create a component that will render your component, providing it a onSize
callback function to get it's size.
class MyContainerComponent extends React.Component {
onSize = (size) => {
console.log('MyComponent')
}
render() {
return <Hello to="🌎" onSize={this.onSize} />
}
}
Zing. Let me know if you have issues/ideas!
react-component-queries
)This library is great, however, it is quite low-level and has some "side-effects":
size
props. This is because any time your component changes in size react-sizeme
will kick in.With these problems in mind I came up with an abstraction in the form of react-component-queries
. This library allows you to define query functions that will operate on the dimensions provided by react-sizeme
and when their criteria are met they will pass a custom set of prop(s) to your components. This solves problem 1 by moving the dimension based logic out of your component. It then solves problem 2 by ensuring that your component will only be called for re-render if any of the prop values change. That saves you some error prone boilerplate.
This allows you to deal with "simpler" props, for example; a boolean flag indicating if the component is square, an enum representing it's size ('small'|'medium'|'large'), a className, or a style object. Whatever you feel is most appropriate for your use case.
So, to recap, some of the benefits of using this abstraction are:
shouldComponentUpdate
is implemented on your behalf.I am not trying to take away from react-sizeme
, but I want to highlight that it's a bit more of a low level HOC, and if you want to use it you should be aware of the problems above and consider using your own abstraction or this one.
Ok, we have a bit of a chicken/egg scenario. We can't know the width/height of your Component until it is rendered. This can lead wasteful rendering cycles should you choose to render your components based on their width/height.
Therefore for the first render of your component we actually render a lightweight placeholder in place of your component in order to obtain the width/height that will become available to your Component. If your component was being passed a className
or style
prop then these will be applied to the placeholder so that it can more closely resemble your Component.
In cases where you have styles/classes contained within your component which directly affect your components proportions, you may want to consider creating an internal wrapped component that you can then pass the className/style into. For example:
import React from 'react';
import cssStyles from './styles.css';
import sizeMe from 'react-sizeme';
class MyComponent extends Component {
render() {
const className = this.props.className;
const { width, height } = this.props.size;
return (
<div className={className}>
My size is {width}px x {height}px
</div>
);
}
}
const MySizeAwareComponent = sizeMe()(MyComponent);
// We create this wrapper component so that our size aware rendering
// will have a handle on the 'className'.
function MyComponentWrapper(props) {
return (
<MySizeAwareComponent className={cssStyles.foo} {...props} />
);
}
export default MyComponentWrapper;
Should you wish to avoid the render of a placeholder and have an eager render of your component then you can use the noPlaceholder
configuration option. Your component will then be rendered directly, however, the size
prop will not contain any data - so you will have to decide how to best render your component without this information. After it is rendered size-me
will do it's thing and pass in the size
prop.
size
data refresh rateThe intention of this library to aid in initial render on a target device, i.e. mobile/tablet/desktop. In this case we just want to know the size as fast as possible. Therefore the refreshRate
is configured with a very low value - specifically updates will occur within 16ms time windows.
If however you wish to use this library to wrap a component that you expect to be resized via user/system actions then I would recommend that you consider setting the refreshRate
to a higher setting so that you don't spam the browser with updates.
Okay, I am gonna be up front here and tell you that using this library in an SSR context is most likely a bad idea. If you insist on doing so you then you should take the time to make yourself fully aware of any possible repercussions you application may face.
A standard sizeMe
configuration involves the rendering of a placeholder component. After the placeholder is mounted to the DOM we extract it's dimension information and pass it on to your actual component. We do this in order to avoid any unnecessary render cycles for possibly deep component trees. Whilst this is useful for a purely client side set up, this is less than useful for an SSR context as the delivered page will contain empty placeholders. Ideally you want actual content to be delivered so that users without JS can still have an experience, or SEO bots can scrape your website.
To avoid the rendering of placeholders in this context you can make use of the noPlaceholders
global configuration value. Setting this flag will disables any placeholder rendering. Instead your wrapped component will be rendered directly - however it's initial render will contain no values within the size
prop (i.e. width
, height
, and position
will be null
).
import sizeMe from 'react-sizeme';
// This is a global variable. i.e. will be the default for all instances.
sizeMe.noPlaceholers = true;
Note: if you only partialy server render your application you may want to use the component level configuration that allows disabling placeholders per component (e.g.
sizeMe({ noPlaceholder: true })
)
It is up to you to decide how you would like to initially render your component then. When your component is sent to the client and mounted to the DOM SizeMe
will calculate and send the dimensions to your component as normal. I suggest you tread very carefully with how you use this updated information and do lots of testing using various screen dimensions. Try your best to avoid unnecessary re-rendering of your components, for the sake of your users.
If you come up with any clever strategies for this please do come share them with us! :)
We make use of the awesome element-resize-detector library. This library makes use of an scroll/object based event strategy which outperforms window resize event listening dramatically. The original idea for this approach comes from another library, namely css-element-queries by Marc J. Schmidt. I recommend looking into these libraries for history, specifics, and more examples. I love them for the work they did, whithout which this library would not be possible. :sparkle-heart:
FAQs
Make your React Components aware of their width and/or height!
We found that react-sizeme demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
A threat actor's playbook for exploiting the npm ecosystem was exposed on the dark web, detailing how to build a blockchain-powered botnet.
Security News
NVD’s backlog surpasses 20,000 CVEs as analysis slows and NIST announces new system updates to address ongoing delays.
Security News
Research
A malicious npm package disguised as a WhatsApp client is exploiting authentication flows with a remote kill switch to exfiltrate data and destroy files.