Search code examples
reactjsreduxreact-reduxreact-routerreact-redux-i18n

Get props from React container to functional component


This is how my container looks like:

class Shipping extends React.PureComponent {
   constructor(props) {
       super(props)
   }
   componentDidUpdate(prevProps) {
       if (prevProps.match.params.shippingId !== this.props.match.params.shippingId) {
        
           this.props.getShippingDetails(this.props.match.params.shippingId)
       }
   }
   render = () => this.props.isLoading ? null : <ShippingView removeOrder={this.props.removeOrder} />
}
const mapStateToProps = ({ shippingDetails}) => ({
    isLoading: shippingDetails.isLoading
})

const mapDispatchToProps = (dispatch) => ({
    getShippingDetails: (id) => dispatch(shippingActions.getShippingDetails(id)),
    removeOrder: (id) => dispatch(shippingActions.removeOrder(id))
})

export default () => Shared.accessPageWrapper([["acess:all"], ["admin:control", "navigation/shopping:view"]], (connect(mapStateToProps, mapDispatchToProps)(Shipping)), <Shared.AccessDeniedView  />)

This is how my functional component looks like:

export const accessPageWrapper = (
    permissionsAllowed = [],
    component = null,
    accessDeniedView,
    accessDenied = true
) => {
    const permissions = useSelector(state => state.user.permissions)
    const permitted = permissionsAllowed.some((permission) => permission.every(el => permissions.includes(el)), false)
    if (permitted) {
        const Component = component
        return <Component />
    }
    return accessDenied ? accessDeniedView : null
}

I'm not able to pass the props through the functional component as following:

const Component = component
return <Component {...props} />

Due to that issue, I'm getting the following error because my prop's prams are undefined.

Uncaught TypeError: Cannot read property 'params' of undefined

I have no idea how to fix this :/ Would you be so kind to help me? Also, I don't want to change the above functional component to a class component. Is there any way I can retrieve the props to the component? Thanks in advance!!


Solution

  • I think you are just missing the return of a component. Higher Order Components consume a component (and other possible parameters) and return a new, decorated component.

    export const accessPageWrapper = (
      permissionsAllowed = [],
      component = null,
      accessDeniedView,
      accessDenied = true
    ) => (props) => { // <-- return a functional component
      const permissions = useSelector((state) => state.user.permissions);
      const permitted = permissionsAllowed.some(
        (permission) => permission.every((el) => permissions.includes(el)),
        false
      );
      if (component && permitted) { // <-- Ensure component exists!
        const Component = component;
        return <Component {...props} />; // <-- spread passed props to Component
      }
      return accessDenied ? accessDeniedView : null;
    };
    

    Probably need to update the export.

    import { accessPageWrapper } from '.....';
    
    ...
    
    export default accessPageWrapper(
      [["acess:all"], ["admin:control", "navigation/shopping:view"]], 
      connect(mapStateToProps, mapDispatchToProps)(Shipping), 
      <Shared.AccessDeniedView />,
    );