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

is it possible to create a custom Scene instead of use original Scene? #3208

Closed
HengCC opened this issue Aug 24, 2018 · 9 comments
Closed

is it possible to create a custom Scene instead of use original Scene? #3208

HengCC opened this issue Aug 24, 2018 · 9 comments

Comments

@HengCC
Copy link

HengCC commented Aug 24, 2018

I want to handle some things in a unified way when the scene trigger onEnter, like:

import React, { Component } from 'react';
import { Scene } from 'react-native-router-flux';
class CustomScene extends Component {
  constructor(props) {
    super(props);
  }

  enterScene = (val) => {
    console.log("Scene onEnter val:");
    if (this.props.onEnter) {
      this.props.onEnter(val)
    }
  }
  render() {
    console.log("scene props:", this.props);
    const { onEnter, on, ...rest } = this.props;
    return (
      <Scene onEnter={this.enterScene} on={this.enterScene} {...rest} >
        {this.props.children}
      </Scene>
    );
  }
}

export default CustomScene;

then use it:

import CustomScene from './Scene';
 <Router>
        <CustomScene key="root">
          <CustomScene key="login" hideNavBar component={RouterComponent.Login} />
        </CustomScene>
</Router>

Is this feasible?

@HengCC
Copy link
Author

HengCC commented Aug 24, 2018

i try this, but got an error:

Cannot read property 'routes of undefined'

@HengCC
Copy link
Author

HengCC commented Aug 25, 2018

i read the source code . I found the scene just as a container, it's not really rendered, So the above solution is not feasible. Is there any other solution that can handle the onEnter event of all routes uniformly?

@daviscabral
Copy link
Collaborator

daviscabral commented Aug 25, 2018

You can try the react-navigation@2 NavigationEvents.

Could you also check if the idea below works? (I haven't actually tested it - and typed it here in the input off the top of my head - it might have errors or typos - help me out on that to get the whole idea behind it 😉).

CustomScene

class CustomScene {
  constructor(props) {
    props.onEnter = this.handleOnEnter;
    super(props);
  }

  handleOnEnter = (val) => {
    console.log("Scene onEnter val:");
    if (this.props.onEnter) {
      this.props.onEnter(val)
    }
  }
}

export default CustomScene;

Adding a onEnter in the Router sounds like a good enhancement - what do you think @aksonov?

@HengCC
Copy link
Author

HengCC commented Aug 27, 2018

@daviscabral thanks! I have tried your idea, but it still doesn't work.
My current solution is to add the onEnter event to each Scene.

@daviscabral
Copy link
Collaborator

daviscabral commented Aug 28, 2018

IGNORE THIS ANSWER

Use the other one I answered below please. #3208 (comment)


I believe the way for doing that (since onEnter from components is always called) is to move the code you want reuse to a module and call it in your components.

class Login extends Component {
  onEnter = myModuleNameUtils.onEnterHandler
}

class Home extends Component {
  onEnter = myModuleNameUtils.onEnterHandler
}

class Profile extends Component {
  onEnter = myModuleNameUtils.onEnterHandler
}

const myModuleNameUtils = {
  onEnterHandler: (val) => {
    // do your stuff here
  }
}

RNRF will call onEnter in these components if you do not set it in the Scene.

@HengCC
Copy link
Author

HengCC commented Aug 28, 2018

I haven't tried this method yet, maybe it's feasible, but I don't think there is any difference between this method and the way that the onEnter event is added directly on the Scene, and this implementation is intrusive to the component. I am not sure if such demand is universal, if it is, as you said, Adding a unified onEnter on the Router may be a better solution.

@daviscabral
Copy link
Collaborator

HoC is also a solution.

const withOnEnterHandler = onEnterHandler => Component => {
  class WrappedComponent extends Component {
    onEnter = val => onEnterHandler(val)

    render () {
      return <Component {...this.props} />;
    }
  }
  return WrappedComponent;
}

@daviscabral
Copy link
Collaborator

But yeah - something on the Stack level would be nice. Let's wait @aksonov come back from vacation to see his opinion about it.

@aksonov
Copy link
Owner

aksonov commented Sep 5, 2018

HoC is good solution, closing this ticket

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants