Git Product home page Git Product logo

hoist-non-react-statics's People

Contributors

andarist avatar bringking avatar bruno12mota avatar danielrosenwasser avatar dawnmist avatar dchambers avatar elevenpassin avatar eps1lon avatar evanlovely avatar gajus avatar garbles avatar jamesreggio avatar kaesonho avatar leipert avatar lyf1999 avatar malgalad avatar michaeldeboey avatar milesj avatar mridgway avatar nemo108 avatar nwshane avatar perrin4869 avatar philipp91 avatar tarabyte avatar trysound avatar vitkon avatar wojtekmaj avatar yangpeiyong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hoist-non-react-statics's Issues

stop hoisting non-enumerables

Hi,

The original reason for having started to hoist non-enumerable properties was babel transpiling static class properties as non-enumerable. Babel no longer does that. Can this be changed back to hoist only enumerables, or can an option be added to hoist non-enumerables or not?
I'm willing to submit a PR changing this if it's welcome

(original change: #3)

Thanks,
Nuno

Support statics defined by inheritance

class A extends React.Component {
  static test3 = 'A';
}
class B extends A {
  static test2 = 'B';
}
class C {
  static test1 = 'C';
}
const D = hoistNonReactStatic(C, B);

console.log('D.test1', D.test1);  // 'C'
console.log('D.test2', D.test2);  // 'B'
console.log('D.test3', D.test3);  // undefined

This is caused by Object.getOwnPropertyNames and Object.getOwnPropertySymbols not deeply resolving inherited properties defined on the prototype chain. I have created a utility to get around this which you can use as a dependency or copy the basic logic object-props.

sorry, not for you code, but possible you know

i did function:

export const withAppContext = (Component:any):any => {

    let r = (props:any):any => {
        return <AppContext.Consumer>
            {(context: any) => {
                return <Component {...props} context={context}/>
            }}
        </AppContext.Consumer>
    };

        if (Component.navigationOptions) {
            Object.defineProperty(r,'navigationOptions',Component.navigationOptions)
            //(r as any)['navigationOptions']= Component['navigationOptions'];
        }

//manually just for test, but also does not work
    Object.defineProperty(r,'navigationOptions', {
        title: 'Home',
    })

    return r;

};

why this method do not provide a static method 'navigationOptions' when i do render

withAppContext (ReactComponent)

?

Minified build in npm package makes auditing difficult

Hi,

While auditing dependencies, I encountered a minified build in this library's npm package. This unfortunately makes it very difficult to audit the package, and I'd like to suggest removing it and/or distributing it outside of npm instead.

I've written an extensive explanation of the problem and the reasons for my suggestion here, so that I don't end up redoing the same explanation in every affected package: https://gist.github.com/joepie91/04cc8329df231ea3e262dffe3d41f848

Thanks!

Transition TypeScript definition to DefinitelyTyped

There has been a lot of churn in the type definitions which I am unable to test since I do not use TypeScript. Since the guidance from the TypeScript team is to use DefinitelyTyped for modules that are not natively written in TypeScript, that is what should be done.

Once a type definition has been published to DefinitelyTyped, I will remove the embedded index.d.ts file.

`isMemo` check always returns false for components

React-is type check methods like isFragment isMemo are only applicable for element types as the readme says, not components.

This package allows you to test arbitrary values and see if they're a particular React element type.

This LOC will always return false here:
https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js#L54

The React-is first checks if the passed param is at least an element else it doesn't check its type at all.

Incorrect AMD definition

The AMD definition does not declare the dependency on react-is and uses the global require, not the AMD local require.

Two possible ways of handling this would be a correct AMD definition here would be either

define(["react-is"], function(ReactIs) {...});

or

define(["require", "react-is"], function(require) { var ReactIs = require("react-is"); ...});

how can I use this package to extract atrributes of dynamic import react component

I have a HOC like this

const asyncComponent = (importComponent) => {
  class WrapComp extends React.Component{
      state = {
          component: null
      }
      componentDidMount(){
          importComponent().then(cmp => {
              this.setState({component: cmp.default});
          });
      }
      render(){
          const {forwardedRef, ...rest} = this.props
          C = this.state.component;
          return C ? <C ref={forwardedRef} {...rest} /> : null;
      }
  }

  return React.forwardRef((props, ref) => {
    return <WrapComp {...props} forwardedRef={ref} />;
  }); 
}

const component = asyncComponent(() => import('./another.js'))

as you can see, because the importComponent is dynamic imported, I cant use this package before the HOC return

Version 1.0.5 missing on master

It seems that there's some unpushed changes somewhere... There's a version 1.0.5 of this package released on npm:

$ npm info hoist-non-react-statics
{ name: 'hoist-non-react-statics',
  description: 'Copies non-react specific statics from a child component to a parent component',
  'dist-tags': { latest: '1.0.5' },
  versions: 
   [ '1.0.0',
     '1.0.1',
     '1.0.2',
     '1.0.3',
     '1.0.4',
     '1.0.5' ],
  maintainers: 'mridgway <[email protected]>',
  time: 
   { modified: '2016-02-02T21:13:42.645Z',
     created: '2015-05-27T23:39:34.473Z',
     '1.0.0': '2015-05-27T23:39:34.473Z',
     '1.0.1': '2015-05-30T23:31:11.202Z',
     '1.0.2': '2015-06-08T23:39:14.515Z',
     '1.0.3': '2015-08-10T20:39:03.169Z',
     '1.0.4': '2016-02-02T19:13:04.294Z',
     '1.0.5': '2016-02-02T21:13:42.645Z' },
/* ... */ }

But package.json on HEAD says the latest version is 1.0.4. :-)

Suggestion: Add explanation to README

I didn't understand what this library did at first, and I think it's a bit tricky for people who are new to React. Would it be worth adding a more detailed explanation of what the library does to the README?

If others think this would be valuable, I can submit a PR with such an explanation.

ReferenceError: require is not defined

Hi~~

I have a react project and I want to upgrade react-redux from v5.0.7 to v5.1.1, but when I restart my project, I get some error from hoist-non-react-statics as follows:

image

hoist-non-react-statics is a dependency of react-redux and I notice that hoist-non-react-statics has changed package.json main field to a cjs file from v2.5.1. The require syntax isn't supported in browser.

Is it a bug for hoist-non-react-statics ???

Typescript types

I see that typescript types consider that the source component and the target should share the same props. But I often use this module with components that have completely different props (because several HoC enhance the source component).

Shouldn't the type declaration allow for source and target to have no props in common ? like so:

function hoistNonReactStatics<Own, Custom>(
    TargetComponent: React.ComponentType<Own>,
    SourceComponent: React.ComponentType<Custom>,
    customStatic?: any): React.ComponentType<Own>;

Please update description in understendable way

"Copies non-react specific statics from a child component to a parent component."

...

hoistNonReactStatics(targetComponent, sourceComponent);

What is a child and what is a parent (targetComponent or sourceComponent)?

Keeping isReactComponent prototype

Hi

I'm currently experiencing an issue passing a HOC directly to another component that is expecting the React Component to have .prototype.isReactComponent available. The HOC is react-intl and it's using this package to clone a WrappedComponent. The prototype property is added by React to allow others to easily check if a function is a React Component, which is used by react-table.

Seeing as this package is cloning React components, should this one prototype property be cloned too?

This current fix is to add this manaully before exporting:

const injected = injectIntl(MyComponent);
injected.prototype.isReactComponent = {};

export default injected

Prop types report missing prop since v3.0.0

Since the latest version I get the misleading warning from PropTypes despite the prop is being provided:

Warning: Failed prop type: The prop xxx is marked as required in Foo, but its value is undefined.

Compare the same code with different versions in CodeSandbox and check the console:

Locally I tried to revert this line:

const objectPrototype = Object.prototype;

Back to this:

var objectPrototype = getPrototypeOf && getPrototypeOf(Object);

And it seemed to work again. I am not sure what's happening there and I did not investegate further, just wanted to share some insights.

Object.getPrototypeOf called on non-object

If i use hoist-non-react-statics In some low version browsers,like oppo r9m android5.1 ,there will be an error in console。
The error information is “Object.getPrototypeOf called on non-object” 。
And there is the reason

Is it better to add some fault-tolerant logic?

Allow react version ^17

Currently the semver matches react v16 only, which introduces duplicated react-is (v16 and v17).

Please tell Version for react-redux

Hi all.
Could you tell me which version I should use for react-redux typescript.

There is import and using it as inner property.
But in current version inner is main object.

import hoistNonReactStatics = require('hoist-non-react-statics');
hoistNonReactStatics.NonReactStatics

Error
./node_modules/@types/react-redux/index.d.ts
Namespace '"C:/work/School6/test/brillder/node_modules/hoist-non-react-statics/index"' has no exported member 'NonReactStatics'

Please

Doesn't hoist static

i'm on nextjs, this package doesn't hoist getInitialProps, which is a non react static method.

v3 and react peer requirement

I'm opening a separate issue for discoverability starting with my original comment #55 (comment)

@mridgway Why is the peer to react >= 14 required? As far as I understood react-is it would just not recognize components from before v14. Since you currently only use react-is to detect types that were added in 16.3.0 this shouldn't be an issue.

In addition I Did some more research and the original PR did not mention any version requirement for react. The RFC and the original commit explicitly say that it has no requirement to react.

This is currently causing trouble with every package that wants to support older and new react versions. Getting all affected to release a new major and drop support for react below 14 just to bump hoist-non-react-statics will take time and wouldn't be needed if we could simply backport v3 to a new minor in v2.

Edit:
So I guess you're refering to facebook/react#12882 (comment)

Which previous versions of react does react-is support?

Should support versions 0.14+

It relies on $$typeof (added in 0.14), so it will not support <= 0.13

But again since forwardRef was only added in 16.3 it wouldn't matter in that case. It's only dangerous if you plan on using isValidElementType which would return false for components in react <= 0.13

Support hoisting of symbol properties

I'm using HOC to annotate components with custom metadata. To avoid name collisions I was planning to use ES2015 Symbols. But this approach fails if component is later wrapped with for example react-redux connect.
Since this library is de facto standard for hoisting statics I thought it would be nice to make it copy symbol properties as Object.assign does.

Made up a PR #17

Describe third argument is docs

There are third argument: 'blacklist'. It's very useful for my situation.
Would you mention it in docs? And I will be sure that it can be used safely.

Reduce bundle size

Hello! I saw that you race for minified size, and I have tried several options to minify the bunde for modern browsers for about 15%:

  • create a let x = true and set all settings from contextTypes: true to contextTypes: x - saves ~20b of minified code
  • rewrite getStatics method to arrow function - 16b of minified code
  • forEach in loop - around 25b
  • caching repeating keys (defaultProps, displayName, propTypes) also gains around 20b
  • exporting function after declaration saves around 30b

Unminified souce is also reduced by 400 bytes

Should I provide a PR for all of this or some points are useless?)

missing dist/ folder in 3.3.0 release on GitHub

Hello,

I'm using some libraries that depend on hoist-non-react-statics and from what I can tell, the latest 3.3.0 version on github does not have the dist/ folder, so the file specified in package.json # main cannot be resolved.

The link I used to download was:

https://github.com/mridgway/hoist-non-react-statics/releases/tag/v3.3.0

Additionally, my yarn installation pointed to:

https://codeload.github.com/mridgway/hoist-non-react-statics/tar.gz/4fbd062b55ccb657b631505728bc043000ece9a5

I'm not sure if this is an issue with my personal yarn installation, issues with libraries that are depending on an incorrect version of this package, or if this library needs to have npm run build run before creating the release - I'm still in "investigative" mode, but thought I'd put this up to see if others are having the same issue or if you knew how to resolve.

Thanks!

Improve typing of third argument

Using typescript the third argument is called 'customStatic'. Which seems to indicate you can provide more statics, rather than provide a list of statics to avoid. I think the name can be more clear.

Remove publishConfig block from package.json

Having publishConfig with hardcoded global registry makes impossible to upload this package to custom local offline mirrors (usually used by companies):

"publishConfig":` {
    "registry": "https://registry.npmjs.org/"
  }

Removing it should not affect regular version release since registry.npmjs.org is default in npm.

React.forwardRef results in propTypes etc. being hoisted

propTypes and defaultProps are still processed statics for react in forwardRef components (other statics might be too but those two were the most straight forward to verify). They should therefore not be hoisted.

Edit:
displayName might be another issue. It's probably safe to assume that FORWARD_RED_STATICS should be merged if the sourceComponent is a forwardRef component instead of replacing all react statics.

full sandbox

Edit: broken example; see #66 (comment) for fixed code

import React from "react";
import ReactDOM from "react-dom";
import hoistStatics from "hoist-non-react-statics";
import PropTypes from 'prop-types';

const App = React.forwardRef((props, ref) => <div {...props} ref={ref} />)
App.propTypes = {
  id: PropTypes.number.isRequired
}

App.defaultProps = {
  children: 'Hello, World',
}

const withDefaultId = id => Component => {
  function EnhancedComponent({innerRef, ...props}) {
    return <Component id={id} {...props} ref={innerRef} />
  }

  return hoistStatics(EnhancedComponent, Component);
}

// we should now be able to savely use AppWithId without propTypes warning
// that `id` is missing since with injected it. But propTypes is being hoisted 
// so react warns anyway
const AppWithId = withDefaultId('default-id')(App);

const rootElement = document.getElementById("root");
ReactDOM.render(<React.StrictMode><AppWithId innerRef={r => console.log(r)} /></React.StrictMode>, rootElement);

Cached global statics

I'm a little bit unsure why this is needed:

var defineProperty = Object.defineProperty;
var getOwnPropertyNames = Object.getOwnPropertyNames;
var getOwnPropertySymbols = Object.getOwnPropertySymbols;
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
var getPrototypeOf = Object.getPrototypeOf;
var objectPrototype = getPrototypeOf && getPrototypeOf(Object);

Are those property lookups considered costful so they are cached? By inlining them we could save 34 bytes (checked on minified and gzipped bundle)

Crash in React Native

I'm getting the following error when using it in React Native (with Debug JS mode disabled)
It fails with version 2.1.0 but it works with 2.0.0 so downgrading is a workaround.

screen shot 2017-07-12 at 12 08 21 pm

latest 2.5.1 and 2.5.2 version break react-apollo

Looks like both 2.5.1 and 2.5.2 versions break react-apollo.

at IncomingMessage.g (events.js:292:16) TypeError: hoistNonReactStatics$1 is not a function
at eval (webpack:///./node_modules/react-apollo/react-apollo.browser.umd.js?:962:20)
at eval (webpack:///./node_modules/react-apollo/node_modules/lodash/_createFlow.js?:68:42)

It works properly with 2.5.0

React 16.3+ forwardRef component

React 16.3+ forwardRef() will return a new component (type is object) that contains a render function and a $$typeof Symbol, and these should not be copied, otherwise may cause some bug

Example to reproduce

import React, { Component, createRef, forwardRef } from 'react';
import hoistStatics from 'hoist-non-react-statics';

function hoist(WrappedComponent) {
	return function createHoistedComponent(TargetComponent) {
		const HoistedComponent = forwardRef((props, ref) => (
			<TargetComponent {...props} forwardedRef={ref} />
		));

		if (WrappedComponent) {
			HoistedComponent.displayName = `hoisted(${WrappedComponent.displayName})`;
			hoistStatics(HoistedComponent, WrappedComponent /* , { render: true } */);
		}

		return HoistedComponent;
	};
}

function extraPropsHoc(extra) {
	return (WrappedComponent) => {
		@hoist(WrappedComponent)
		class Bar extends Component {
			render() {
				const { forwardedRef, ...props } = this.props;
				return <WrappedComponent {...props} {...extra} ref={forwardedRef} />;
			}
		}
		return Bar;
	};
}

@extraPropsHoc({ foo: 'foo' })
@extraPropsHoc({ bar: 'bar' })
class Foo extends Component {
	static displayName = 'Foo';

	log() {
		console.log('this.props', this.props);
	}

	render() {
		return <h1>Hello</h1>;
	}
}

export default class App extends Component {
	ref = createRef();

	componentDidMount() {
		this.ref.current.log();
	}

	render() {
		return <Foo ref={this.ref} />;
	}
}

Result

this.props {bar: "bar"}

Expect

this.props {foo: "foo", bar: "bar"}

If I uncomment hoistStatics(HoistedComponent, WrappedComponent /* , { render: true } */), it will work as expected.

Env

When hoisting: Keep prop value if context value is undefined

I'm using script type="module" to load two react components into the browser.
Parent provides a context.
Child consumes a context.

As long as both components come from the same bundle the Child gets the correct context.

However if I load the components from their own bundles. The context is lost.

My workaround for this is to pass in the context as props.
But then the Child cannot be a context Consumer, because it will overwrite the props.

So my question is, if some property exists both as a prop and in the context, which should win?

If the property is undefined in the context it would be nice to keep the prop.

(If anyone has other suggestions on how to make the correct context available to the child, please let me know.)

Prevent overwriting target statics

Is there any interesting in preventing this function from overwriting the statics of the target (either by default or by change of the function's API)?

error: Error: While trying to resolve module `hoist-non-react-statics`

hi , Do you have any advice to solve this problem, friends?

`

error: Error: While trying to resolve module hoist-non-react-statics from file D:\xxx\xx\node_modules\react-redux\lib\components\connectAdvanced.js, the package D:\xx\xx\node_modules\hoist-non-react-statics\package.json was successfully found. However, this package itself specifies a main module field that could not be resolved (D:\xx\xx\node_modules\hoist-non-react-statics\dist\hoist-non-react-statics.cjs.js. Indeed, none of these files exist:
`


package.json:
{
"name": "xx",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"@react-native-community/art": "^1.2.0",
"@react-native-community/async-storage": "^1.12.1",
"@react-native-community/masked-view": "^0.1.11",
"@react-native-community/netinfo": "^7.1.7",
"@react-native-picker/picker": "^2.2.1",
"@react-navigation/native": "5.x",
"axios": "^0.26.0",
"jalali-moment": "^3.3.10",
"json-beautify": "^1.1.1",
"native-base": "^3.3.4",
"react": "17.0.2",
"react-native": "0.67.3",
"react-native-dialog-input": "^1.0.8",
"react-native-exit-app": "^1.1.0",
"react-native-gesture-handler": "^2.2.0",
"react-native-image-crop-picker": "^0.37.2",
"react-native-image-slider-banner": "^1.0.3",
"react-native-indicator": "^1.2.2",
"react-native-modal": "^13.0.0",
"react-native-safe-area-context": "^3.1.9",
"react-native-screens": "^3.10.2",
"react-native-slideshow": "^1.0.1",
"react-native-svg": "^12.1.0",
"react-native-svg-transformer": "^1.0.0",
"react-native-textinput-effects": "^0.6.2",
"react-native-toast-message": "^2.1.1",
"react-native-vector-icons": "^9.0.0",
"react-native-webview": "^11.17.0",
"react-navigation": "^4.4.4",
"react-navigation-stack": "^2.10.4",
"react-redux": "^7.2.2",
"redux": "^4.1.2",
"redux-persist": "^6.0.0",
"reselect": "^4.1.5",
"rn-modal-picker": "^0.3.2"
},
"devDependencies": {
"@babel/core": "^7.17.5",
"@babel/runtime": "^7.17.2",
"@react-native-community/eslint-config": "^3.0.1",
"babel-jest": "^27.5.1",
"eslint": "^8.11.0",
"jest": "^27.5.1",
"metro-react-native-babel-preset": "^0.69.0",
"react-test-renderer": "17.0.2"
},
"jest": {
"preset": "react-native"
}
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.