Uncaught Invariant Violation: 
You must pass a component to the function returned by connect.Instead received {}
Copy the code

In the project these days, I encountered a scenario where REF forwarding + connect was used together.

React.forwardRef API react. forwardRef API react. forwardRef API The react. forwardRef return value is not correct.

The preceding error message is displayed, and the error code is as follows.

const Example = React.forwardRef((props) => {  
    return (
        <div>
            Example
        </div>  
    );
})

export default connect(({ example }) => {
    return { example: example.example }
})(Example);
Copy the code

Checked it out on the nuggets and settled it according to the big man’s proposal. Thanks for sharing!

– React-connect using forwardRef problem.

Correct code:

const Example = (props) => { return ( <div ref={props.refInstance}>Example</div> ); } const Component = connect(({ example }) => { return { example: example.example } })(Example); export default React.forwardRef((props, ref) => <Component {... props} refInstance={ref} />)Copy the code

At this point, the problem is solved. The solution is to link Redux with Connect first and then perform ref forwarding.

Lazy cancer attack, thinking can not go to modify the order before. Namely: forward first, link Redux later.

After analyzing the source code, the following conclusions are drawn

  • The forwardRef return value is a virtual DOM node. Connect ()(WrappedComponent) is a render function and passing the forwardRef return value to Connect will cause an error.
  • The forwardRef (options) parameter of connect: if the forwardRef is true (ref through), the forwardRef (options) parameter of connect is false (no forwardRef). The reason why REF forwarding is needed: When using CONNECT wrapped UI components, it directly exposes the wrapped higher-order components, not the UI components themselves. So ref links to wrapped higher-order components, and ref links to UI components itself requires forwarding.

The react. forwardRef return value is an object and Render is the UI component. Reference: the React. ForwardRef

With this structure, appending render after the react. forwardRef works fine, essentially passing a UI component to Connect.

Const Example = React. ForwardRef ((props) => {return <div>Example</div>}).render Export default connect(({example}) => {return {example: example.example}})(example);Copy the code

The WrappedComponent is the render props in the image above, which determines whether the WrappedComponent is a valid type (virtual DOM? Personal speculation, no further investigation for the time being)

The WrappedComponent is the UI component and the react. forwardRef return is an object. You can see that the error message above matches the error message at the beginning of the article.

The forwardRef variable below is the forwardRef of connect’s fourth parameter, Options. Combining the above image, you can see that the reactReduxForwardedRef was forwarded to our UI component. The forwardRef (options) parameter only controls whether the refs are forwarded within the connect and does not affect the react. forwardRef function

Reference:

React, react-redux, hoist-non-react-statics, Redux