Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A List of antd's components that cannot work with HOC #4853

Closed
benjycui opened this issue Feb 14, 2017 · 75 comments
Closed

A List of antd's components that cannot work with HOC #4853

benjycui opened this issue Feb 14, 2017 · 75 comments
Labels
🗣 Discussion ❓FAQ issues would be discussed a lot Inactive

Comments

@benjycui
Copy link
Contributor

benjycui commented Feb 14, 2017

It is not a common use case, so it's low priority. But we still can discuss and try to make it better:

@benjycui
Copy link
Contributor Author

benjycui commented Aug 17, 2017

It's difficult, for some components use key as part of API, we cannot fix this until we rename all the API's names. e.g.

key => id
expandedKeys => expandedIds
selectedKeys => selectedIds
....

It will be a breaking change, but such kind of breaking change can be resolve by antd-codemod.

@benjycui
Copy link
Contributor Author

SO, do you think that it is worthy doing so?

@afc163

This comment has been minimized.

@MacKentoch
Copy link

Not fan of codemod solution.
Just my point of view, but, I believe that sadly for most of people it is more repulsive than welcomed.

Embedding components into custom components is a common practice in React.

Please fix it and see ant-design adoption fast increase with no doubt.

Ant Design is really appealing and is the first library that makes me want to leave react-bootstrap.

@benjycui
Copy link
Contributor Author

@MacKentoch

It's difficult, for some components use key as part of API, we cannot fix this until we rename all the API's names.

@benjycui
Copy link
Contributor Author

@afc163 if we cannot rename those APIs, then we can not resolve this problem. But we can provide a work around, see: react-component/collapse#73 (comment)

Do you think that we should add this to documentation?

@MacKentoch
Copy link

@benjycui I understand.

Anyway, it is not blocking after all.

Thank you for taking time answering.

@ramiel
Copy link

ramiel commented Aug 28, 2017

@benjycui I was investigating the workaround you proposed but I think it is not a proper solution. Usually when you wrap a component you want also to have some internal state. With the solution proposed this is not possible.
Also I think this is not a little problem. Not being able to isolate common components means having the same code repeated lot of times inside an application. If the application is big I would consider not to adopt antd at all. Please consider this as a constructive critic.
Thanks for your work!

@bodaso
Copy link

bodaso commented Oct 9, 2017

Agreed to say this is not a small problem and it's something I did not expect of when I started using Ant Design library, the good practice of custom components are used throughout React projects. Personally, I really like Ant Design, but for some, this could be a dealbreaker. Would really love to see this gets improved in the upcoming Ant Design v3.

@mitjade
Copy link

mitjade commented Nov 3, 2017

Please find a solution for this in v3.

@yesmeck
Copy link
Member

yesmeck commented Nov 3, 2017

Can be resolved after this package released (maybe).

mitjade referenced this issue in sysgears/apollo-universal-starter-kit Nov 7, 2017
@yesmeck
Copy link
Member

yesmeck commented Nov 13, 2017

#5540

@ryanbas21
Copy link

just ran into this trying (sorry if this is wrong) to create a navbar using menu and nesting React Router <Link /> tags in the Menu with <Icon />.

Is there a more preferred solution?

@abenhamdine
Copy link
Contributor

abenhamdine commented Dec 5, 2017

IMHO, this thread should be in the official docs, because this issue is likely to be a dealbreaker for many users.
The docs should also mention react-component/collapse#73 (comment) as an alternative when no state is needed.

@ChuckJonas
Copy link
Contributor

ChuckJonas commented Jan 5, 2018

I would have definitely appreciated mention of this in the documentation! I was trying to do something like this and wasted quite a bit of time because it doesn't work.

<Collapse>
   <MyCollapseItem />
   <MyCollapseItem2 />
</Collapse>

Where MyCollapseItem & MyCollapseItem2 render the Collapse.Panel.

Also, now that react16 allows you to return arrays of components from render, being able to do this would be especially helpful. Otherwise, prevent duplicate code is challenging.

@lednhatkhanh
Copy link

Any updates on this?

@hugobarragon
Copy link
Contributor

Cant create a HOC/custom component around Column component for code splitting & custom handling, using getColumnX() does not work because cant have internal hooks

@DeepAnchor
Copy link

DeepAnchor commented Jul 12, 2021

For Typescript users out there:

If you want to wrap inner components like Collapse.Panel with custom behaviour, all you have to do is add CollapsePanelProps to the props definition of your wrapper component and then spread the props in the actual Panel component that is returned. i.e -

import {  CollapsePanelProps, Panel } from "antd"

type PanelWrapperProps = {
  // your panel wrapper props
} & CollapsePanelProps

const PanelWrapper = (props: PanelWrapperProps) => {
  return (
     <Panel {...props} />
  )
}

You can see what's happening under the hood here: The Collapse clones all of its direct children (which it expects to be Panel) and injects additional props into them. So all you need to do is allow any arbitrary direct child of Collapse to accept those props.

You can also override whichever props you want like isActive, just make sure you add it after the {...props} spread. This will allow you to have granular control over the Panel's behaviour. I.e -

const PanelWrapper = (props: PanelWrapperProps) => {
  const [state, setState] = useState<{isActive:boolean}>({isActive:false})
  return (
     <Panel {...props}  isActive={state.isActive} onItemClick={()=>{setState((prev) => !prev.isActive)}} />
  )
}

@github-actions github-actions bot removed the Inactive label Jul 12, 2021
@Quadrition
Copy link

Quadrition commented Aug 15, 2021

For Typescript users out there:

If you want to wrap inner components like Collapse.Panel with custom behaviour, all you have to do is add CollapsePanelProps to the props definition of your wrapper component and then spread the props in the actual Panel component that is returned. i.e -

import {  CollapsePanelProps, Panel } from "antd"

type PanelWrapperProps = {
  // your panel wrapper props
} & CollapsePanelProps

const PanelWrapper = (props: PanelWrapperProps) => {
  return (
     <Panel {...props} />
  )
}

You can see what's happening under the hood here: The Collapse clones all of its direct children (which it expects to be Panel) and injects additional props into them. So all you need to do is allow any arbitrary direct child of Collapse to accept those props.

You can also override whichever props you want like isActive, just make sure you add it after the {...props} spread. This will allow you to have granular control over the Panel's behaviour. I.e -

const PanelWrapper = (props: PanelWrapperProps) => {
  const [state, setState] = useState<{isActive:boolean}>({isActive:false})
  return (
     <Panel {...props}  isActive={state.isActive} onItemClick={()=>{setState((prev) => !prev.isActive)}} />
  )
}

If you want to pass other props beside PanelWrapperProps you can do it like this:

interface MyComponentProps {
  key: string | number;
  header: ReactNode;
  antdProps?: CollapsePanelProps;
  myOtherProp: string;
}

const MyComponent: FC<MyComponentProps> = ({
  key,
  header,
  myOtherProp,
  ...antdProps
}) => (
  <Panel {...antdProps} key={key} header={header}>
    <p>Something</p>
  </Panel>
);

@mellis481
Copy link
Contributor

mellis481 commented Oct 13, 2021

For posterity, I thought I'd share a workaround (hack?) that partially works for Tabs and may work for other components that ant-design doesn't allow to be extended by an HoC. Take a look at this example.

As you can see, it requires the wrapper component to be called in a function manner rather than via JSX. It's an atypical DX, for sure.... The biggest remaining limitation for me, though, is that you can't control the className at the tab level; you can only wrap the tab contents with a class. So this workaround may or may not work for you, but I thought I'd share.

@cangSDARM
Copy link

cangSDARM commented May 17, 2022

Is there an update now...? Low priority should also be considered.

soft-passion pushed a commit to soft-passion/eth-hot-wallet that referenced this issue May 31, 2022
@moonjoungyoung
Copy link

@abenhamdine

God, I'm sorry for the late response.
I read the thread, of course.

#4853 (comment)
As in the above comment, the problem was not dealt with in the document at the time, and various expedients had to be used to solve it.
It is fortunate that the problem seems to be solved gradually as the version goes up, but I think there are still some problems left.

@afc163
Copy link
Member

afc163 commented Jul 1, 2022

https://codesandbox.io/s/panel-separated-collapse-forked-67495r?file=/PanelElement.js

@ChambreNoire
Copy link

Still no workaround for Descriptions.Item ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🗣 Discussion ❓FAQ issues would be discussed a lot Inactive
Projects
None yet
Development

No branches or pull requests