admin管理员组

文章数量:1124801

I am trying to use a legacy class component (I can't modify it) that goes like this:

class LegacyComponent {
    render() {
        const {
            customComponent: CustomComponent,
        } = this.props;

        return (
            <div>
                    {CustomComponent ? (
                        <CustomComponent />
...

Inside my functional component I want to pass a component with props to this legacy component, let's say

<MyCustomComponent prop1={prop1} prop2={prop2}>

When I try to do it like this:

<LegacyComponent customComponent={<MyCustomComponent prop1={prop1} prop2={prop2}>}/>

it will not work and throw an error Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object..

On the other hand when I would use a function like this:

<LegacyComponent customComponent={() => <MyCustomComponent prop1={prop1} prop2={prop2}>}/>

it would technically work, but the component would render from scratch (reinitialize) every time my parent component rerenders.

I thought about using memo or useCallback, but whenever the dependencies change the component is also reinitialized from scratch so that is not working.

How can I make LegacyComponent naturally rerender with props changed instead of being reinitialized / rendered every time parent component rerenders?

I am trying to use a legacy class component (I can't modify it) that goes like this:

class LegacyComponent {
    render() {
        const {
            customComponent: CustomComponent,
        } = this.props;

        return (
            <div>
                    {CustomComponent ? (
                        <CustomComponent />
...

Inside my functional component I want to pass a component with props to this legacy component, let's say

<MyCustomComponent prop1={prop1} prop2={prop2}>

When I try to do it like this:

<LegacyComponent customComponent={<MyCustomComponent prop1={prop1} prop2={prop2}>}/>

it will not work and throw an error Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object..

On the other hand when I would use a function like this:

<LegacyComponent customComponent={() => <MyCustomComponent prop1={prop1} prop2={prop2}>}/>

it would technically work, but the component would render from scratch (reinitialize) every time my parent component rerenders.

I thought about using memo or useCallback, but whenever the dependencies change the component is also reinitialized from scratch so that is not working.

How can I make LegacyComponent naturally rerender with props changed instead of being reinitialized / rendered every time parent component rerenders?

Share Improve this question asked 2 days ago user29124046user29124046 211 silver badge1 bronze badge New contributor user29124046 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
Add a comment  | 

1 Answer 1

Reset to default 1

If you can't modify your LegacyComponent, then you need another way of passing data from parent to child

props is one way for doing this. Another way is by using React context

const DataContext = React.createContext()

const useDataContext = () => {
    return React.useContext(DataContext)
}

const MyCustomComponent  = () => {
    const {prop1, prop2} = useDataContext()

    ...
}
...
<DataContext.Provider value={{prop1, prop2}}>
   <LegacyComponent customComponent={MyCustomComponent} />
</DataContext.Provider>

If necessary, you can optimize performance by memoizing the value of the provider.

value={React.useMemo(() => ({prop1, prop2}), [prop1, prop2])}

本文标签: