GithubHelp home page GithubHelp logo

Comments (12)

istarkov avatar istarkov commented on July 20, 2024 1

In my projects I never used withProps.
All additional properties I need, I could define in defaultProps HOC.

I understand that in React defaultProps is the part of public component interface,
but having HOC that do almost the same, it's more easy for me to just use defaultProps in all cases instead of withProps. (I never got situations where I need to hide and override props from parent)

Now about @npbee comment above - yes current implementation is buggy.
And he is right about asking you were going for a way to only compute the input props once or if you wanted it to be more like mapProps.

IMHO withProps is not needed at all.

  • for a way to only compute the input props once it will be best to rewrite defaultProps allowing function of props as argument.
  • for all other ways mapProps and withHandlers will be enough.

So I suggest to remove withProps method and allow props to be a function. (This will break React defaultProps similarity a little.)

from recompose.

npbee avatar npbee commented on July 20, 2024 1

I agree that withProps could be a potential pruned helper. @wuct made some good points above for that case. Since I made the issue I haven't ended up using withProps myself at all. But, I think the PR will be helpful just to fix up the current implementation while it's being decided. Thanks!

from recompose.

wuct avatar wuct commented on July 20, 2024

Thanks @npbee, I did not notice that withProps accepts function.
Regarding there is no difference between withAttachedProps and withProps with a function as first parameter, I would like to propose another implementation.

const withProps = (input, BaseComponent) => {
  return ownerProps => {
    props = isFunction(input)
      ? input(ownerProps) 
      : input
    return createElement(BaseComponent, {
      ...ownerProps,
      ...props
    })
  }
}

We can use it like mapProps but more concisely in some cases.

withProps(props => ({ foo: doSomething(props) }))

is same as

mapProps(props => ({
  ...props,
  foo: doSomething(props)
}))

However, I never use withProps currently. In my opinion, mapProps and withAttachedProps are enough to replace withProps totally.

from recompose.

npbee avatar npbee commented on July 20, 2024

Hi @wuct, good points! In fact I ended up using mapProps in the same way you suggested and it worked fine.

Though I could see some benefit to having withProps around still, even if just for semantics. When using the withProps helper, it's more clear to me that I'm providing additional props to the component. Whereas to achieve the same effect with mapProps you have to remember to always include the props you were given as an argument along with your mapped props. That said, I could easily make my own withProps helper using the mapProps to get the functionality we're discussing.

Also just to clarify, if I'm not mistaken the withAttachedProps is a bit different than mapProps or withProps in that it attaches the props to a class instance rather than passing along as regular props. So any props returned from withAttachedProps do not change over the lifetime of the component.

from recompose.

wuct avatar wuct commented on July 20, 2024

@npbee I agree with you! When it comes to append additional props, using withProps is more semantic. And you are right about withAttachedProps. I forgot that difference. Thanks for clarify.

Since the props appended by withProps is design to update with the component lifecycle, I think we could also provide withPropsOnChange, like mapPropsOnChange, which would works well together with pure when we want to append reference props.

The signature of withPropsOnChange could be:

withPropsOnChange(
  depdendentPropKeys: Array<string>,
  propsMapper: (dependentProps: Object) => Object,
  BaseComponent: ReactElementType
): ReactElementType

from recompose.

npbee avatar npbee commented on July 20, 2024

That seems logical to me. So then would it make sense to just build that function using the mapPropsOnChange internally? Something like:

const withPropsOnChange = (depdendentPropKeys, propsMapper, BaseComponent) => {
  return mapPropsOnChange(
    dependentPropKeys, 
    props => ({ ...props, ...propsMapper(props) }), 
    BaseComponent
);

We could probably do something similar with withProps as well.

But I'm beginning to agree more with your first point that maybe withProps is better suited as a user-defined helper using mapProps, at least in the form where it accepts a function. It'd be similar to the stance on omitProps here in the docs: https://github.com/acdlite/recompose/blob/master/docs/API.md#mapprops. Maybe it's just better to have withProps only accept an object and if you need to use a function, use mapProps.

from recompose.

wuct avatar wuct commented on July 20, 2024

Haha, do you mind to provide some real world cases of using withProps in the object-accepting form?

from recompose.

npbee avatar npbee commented on July 20, 2024

Well my original reason for opening the issue was because I was trying to do a wacky pass-through type function that passes owner props through a higher-order component to its children. Something like: https://jsfiddle.net/npbee/av42w2u1/6/

I've kind of gone a different direction and it could definitely be done using mapProps but withProps seemed more appropriate at the time for what I was trying to do.

from recompose.

wuct avatar wuct commented on July 20, 2024

Thanks for your info! It seems like mapProps is more appropriate in your case. However, I am still curious about why @acdlite added getProps into withProps. Maybe there are some cases need to use withProps in that way.

from recompose.

acdlite avatar acdlite commented on July 20, 2024

I believe this is closed by the updated docs in #134. Let me know if it still needs work.

from recompose.

npbee avatar npbee commented on July 20, 2024

I think the function form of withProps might still be a little off.

At the point where input function is called, getProps is still undefined:

const withProps = input => BaseComponent => {
  let getProps
  const props = isFunction(input)
    ? input(getProps)      // <----------- `getProps` is undefined here
    : input

  return ownerProps => {
    getProps = () => ownerProps
    return createElement(BaseComponent, {
      ...ownerProps,
      ...props
    })
  }
}

Also, the docs indicate that the input accepts the owner props directly, but the implementation suggests that it accepts a function that returns the owner props, kind of like the now deprecated withAttachedProps.

It seems like the implementation should be something like:

const withProps = input => BaseComponent => {
  return ownerProps => {
    const props = isFunction(input)
      ? input(ownerProps)
      : input

    return createElement(BaseComponent, {
      ...ownerProps,
      ...props
    })
  }
}

Although I'm not sure if you were going for a way to only compute the input props once or if you wanted it to be more like mapProps. I'd be happy to send a PR or contribute in some way but I just wasn't sure if this was the original implementation you had in mind.

from recompose.

istarkov avatar istarkov commented on July 20, 2024

BTW, as withProps allows to simplify mapProps in most cases, and we have withPropsOnChange, PR #137

from recompose.

Related Issues (20)

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.