npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

props-overrider

v0.0.3

Published

```js import { defaultPropsWithScope, ScopeWrapper } from 'props-overrider'

Downloads

11

Readme

Usage

import { defaultPropsWithScope, ScopeWrapper } from 'props-overrider'

defaultPropsWithScope(Button, {
  styles: newStyle,
  style() {
    return this.props.width === 'fixed' ? Style.fixedRaw : {}
  },
}, {
  item: {
    style: {
      backgroundColor: '#654321',
    }
  }
})

<ScopeWrapper scope='item'>
  <SomeComponentThatContainsButtonInside />
</ScopeWrapper>

Why

RN 的样式是通过组件的 style props 来设置的,虽然属性与 CSS 类似,但实际上工作原理不同,因此覆盖样式会遇到一些比较麻烦的问题。

CSS 因为其独立于 html 存在,因此我们可在任意位置进行样式的重载和覆盖,只需要确保样式能正确匹配元素以及优先级正确即可,非常方便。但 RN 的 style 关联在组件实例上,就严格受到 js 作用域和参数传递的限制。

当所有的组件都在开发者自己的控制范围内时,这个问题还是比较好解决的,因为我们总是可以修改组件以及行为来满足我们对样式的需求。但当我们使用一些三方库作为基础组件(如 antd.mobile)时,这个问题就变得有点纠结了。

考虑如下场景:

class A extends Component {
	render() {
    // render some element
  }
}
class B extends Component {
  render() {
    return (
      <View><A /></View>
    )
  }
}
class C extends Component {
  render() {
    return (
      <View><B /></View>
    )
  }
}

组件 A 、B 、C 都来自于三方库,我们用到了组件 C 然后想要覆盖组件 A 的样式。最直观也是最笨的方法是,把三个组件全部重写一遍:

class MyA extends Component {
	render() {
    return <A style={myOverrideStyle} />
  }
}
class MyB extends Component {
  render() {
    return (
      <View><MyA /></View> // 为了使用 MyA ,只能把 B 整个抄过来,只为了替换掉里面对 A 的使用
    )
  }
}
class MyC extends Component {
  render() {
    return (
      <View><MyB /></View> // 并且还进一步的要传染到 C
    )
  }
}

稍微好一点的办法是,利用 React 的 defaultProps :

// 通常我们是这么用 defaultProps 的
class SomeComp extends Component {
  static defaultProps = {
    return { style: { color: 'blue' } }
  }
}

// 但实际上我们可以直接覆盖 A 的 defaultProps 方法
const oldDefaultProps = A.defaultProps
A.defaultProps = Object.assign({}, oldDefaultProps, { style: { color: 'blue' } })

用这种方式,我们可以在全局层面直接替换掉 A 的默认 style 样式,从而避免对 B 和 C 的重写。但问题还没有得到完全的解决,现在假设我们有一个第三方组件 D 也使用了组件 A ,而我们希望 A 在 D 中的样式和 A 在 C 中的样式是不同的。这种情况在 CSS 中很常见,我们只需要在父 class 下覆盖样式即可,但是在 RN 的场景下,一种方式是借助 context 和一点点 trick :

class SubA extends A {}
SubA.prototype.render = A.prototype.render
A.contextTypes = { scope: React.PropTypes.string }
A.prototype.render = function render() {
  const scope = this.context.scope || 'GLOBAL'
  const style = getStyleByScope(scope)
  return <SubA {...this.props} style={style} />
}

在考虑更多的细节并且通用化到除了 style 之外的 props 之后(有可能第三方组件会使用 styles 来一次传入多组 style),最终解决方案请参考代码中的 src/index.js