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

Unable to use {forwardRef: true} option of observer HOC #2524

Closed
ghost opened this issue May 29, 2020 · 13 comments
Closed

Unable to use {forwardRef: true} option of observer HOC #2524

ghost opened this issue May 29, 2020 · 13 comments
Labels
✌ duplicate 🎁 mobx-react Issue or PR related to mobx-react package

Comments

@ghost
Copy link

ghost commented May 29, 2020

Intended outcome

I would like to forward a ref to an observed component as per my current understanding of https://mobx-react.js.org/observer-hoc

const MyObserverComponent = observer(
  (props, ref) => {
    return <div ref={ref}>My Observer Component</div>;
  },
  { forwardRef: true }
);

Actual outcome

As per codesandbox below, React chokes:

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Warning: Unexpected ref object provided for div. Use either a ref-setter function or React.createRef().

The above error occurred in the

component:
in div (at App.js:29)
in _c4 (at App.js:18)
in div (at App.js:16)
in App (at src/index.js:9)
in StrictMode (at src/index.js:8)

How to reproduce the issue

https://codesandbox.io/s/inspiring-colden-uettu?file=/src/App.js

Versions

react: 16.12.0
mobx: 5.15.4
mobx-react: 6.2.2

@danielkcz
Copy link
Contributor

Thanks for the report. That option works only with mobx-react-lite. However, I don't see any reason why it shouldn't be here as well. I will leave this open and PR is welcome.

@ghost
Copy link
Author

ghost commented May 30, 2020

Sorry, I'm still trying to grasp the relationship between mobx-react and mobx-react-lite. I appreciate the latter is with hooks.

Am I correct in saying that mobx-react-lite is its own library with a degree of independence from mobx-react and can be used in a hooks only implementation, but since mobx-react includes mobx-react-lite in its packaging, the mobx-react-lite API becomes part of the mobx-react API, but with exceptions (like this example) that may be in mobx-react-lite and not mobx-react but are documented in mobx-react for consistency?

@danielkcz
Copy link
Contributor

That is correct. Perhaps this overview will help you? https://mobx-react.js.org/libraries

The observer in mobx-react is slightly different because it needs to take care of class components too. The forwardRef option was added to mobx-react-lite much later out of specific need and nobody ever asked for it in mobx-react.

Actually, looking at the code, it seems that you should be able to wrap to React.forwardRef directly along with observer call.

@danielkcz
Copy link
Contributor

Yea, here is a quick demo.

https://codesandbox.io/s/xenodochial-wiles-3zvwk?file=/src/App.js

Such inconsistency is of course bad for any future migrations. I am thinking we should probably make it work the same way in mobx-react-lite instead of extra option.

@yuwanlin
Copy link

@FredyC thank you, It help me a lot. the demo is useful.
for a function component, It seems

import {  inject } from 'mobx-react';
import { observer } from 'mobx-react-lite';

export default inject('commonStore')(observer(GamePage, {
  forwardRef: true
}));

and

import {  observer, inject } from 'mobx-react';
export default inject('commonStore')(observer(React.forwardRef(GamePage)));

both work.

@MoonBall
Copy link
Contributor

@FredyC From code, there is an intentional behavior for case under discussion.

@danielkcz
Copy link
Contributor

I think you are missing the point here. It should work the same way across both libraries.

@MoonBall
Copy link
Contributor

MoonBall commented Jul 28, 2020

I think you are missing the point here. It should work the same way across both libraries.

@FredyC I mean the below code should not work because of the code. The comment of source code is for this case. So this case maybe not a bug.

const MyObserverComponent = observer(
  (props, ref) => {
    return <div ref={ref}>My Observer Component</div>;
  },
  { forwardRef: true }
);

@yuwanlin
Copy link

yuwanlin commented Aug 1, 2020

@MoonBall the code you mentioned is source code of mobx-react-lite... It work in this case. But mobx-react doesn't work in this case.

@yuwanlin
Copy link

yuwanlin commented Aug 1, 2020

Thanks for the report. That option works only with mobx-react-lite. However, I don't see any reason why it shouldn't be here as well. I will leave this open and PR is welcome.

I am very interested in fixing this problem. Is there anything I need to pay attention to?(eg: which version should I fix it?)

@danielkcz
Copy link
Contributor

@yuwanlin I am thinking it should work the other way around and expand mobx-react-lite to work with React.forwardRef directly instead of extra option. And possibly using that option could produce a one-time warning about deprecation and remove it from the next major. So if you are interested in that, go ahead.

@danielkcz danielkcz transferred this issue from mobxjs/mobx-react Oct 18, 2020
@danielkcz danielkcz added 🎁 mobx-react Issue or PR related to mobx-react package 🐛 bug labels Oct 18, 2020
@danielkcz
Copy link
Contributor

Even though this issue holds more information, the #2527 is more up to date. Closing this as duplicate.

@pauldasslier
Copy link

Hello!
I did same issue and it works for me. Try this:
const MyComponent = compose(inject('profile'), injectIntl)(observer(CommentsCreationField));
export default React.forwardRef((props, ref) => <MyComponent {...props} forwardedRef={ref} />);

This helps me: reduxjs/react-redux#914 (comment)
forwardRef should be outside

@mobxjs mobxjs locked as resolved and limited conversation to collaborators Apr 21, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
✌ duplicate 🎁 mobx-react Issue or PR related to mobx-react package
Projects
None yet
Development

No branches or pull requests

4 participants