Export React component with two property - javascript

I'm using MaterialUI and I have to export my components like this:
import withStyles, { WithStyles } from "#material-ui/core/styles/withStyles";
...
export default withStyles(styles)(Users);
Now I started to use i18next to use internationalization in my project but it want me to export my component like this:
export default translate("common")(Users);
The question is how can I satisfy both? How can I export with withStyles and translate?
Any help is appreciated

Both of those pieces of code produce a new component, so you can feed the result of one into the other. Done in one line, it would look like this:
export default withStyles(styles)(translate("common")(Users));
Or if it makes it easier to follow, here it is split on two lines.
const TranslatedUsers = translate("common")(Users);
export default withStyles(styles)(TranslatedUsers);

The purpose of higher-order components is to provide a way for components to be efficiently composed:
export default translate("common")(
withStyles(styles)(Users)
);
It can be flattened with composition helpers, e.g. recompose:
import { compose } from 'recompose'
export default compose(
translate("common"),
withStyles(styles)
)(Users);

Related

Exporting component using i18n's useTranslation and redux's connect HOCs

My App has used Redux for a long time, with the component exports looking like
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);
I'm now introducing i18n's translation library and would like to use the HOC that is included with the useTranslation.
I've attempted a few different ways and seen that Redux has a connect piece of functionality that is supposed to combine HOCs if I understand correctly, however I cannot get this to work.
export default connect(useTranslation(), connect(mapStateToProps, mapDispatchToProps))(MyComponent);
When I load the browser I am shown:
Uncaught ReferenceError: process is not defined
Am I missing something here?
useTranslation is not a HOC, you want withTranslation. That will look like this:
export default connect(mapStateToProps, mapDispatchToProps)(withTranslation()(MyComponent));
Or, since the order doesn't matter:
export default withTranslation()(connect(mapStateToProps, mapDispatchToProps)(MyComponent));
Nesting multiple HOCs can be hard to read, so it may be easier to use a compose utility function. Redux even includes one:
import { compose, connect } from 'redux';
//...
export default compose(
connect(mapStateToProps, mapDispatchToProps),
withTranslation()
)(MyComponent);

Import methods of the components instead of the binding function

export default withModalMounter(injectIntl(Poll));
I want to extract Poll while importing it in a different component. It looks that that while importing I am just able to import withModalMounter component and not the methods of Poll.
Since you want to import Poll component without withModalMounter too. You can export it like below
const withInjectIntl = injectIntl(Poll);
export { withInjectIntl as Poll };
export default withModalMounter(withInjectIntl);
Post this you can import it like
import PollWithMounter, { Poll } from 'path/to/poll';

Named import in React

In this line:
import React, { Component } from "react";
why the braces are only around Component and not also on 'React'?
Here's a great answer that explains default and named imports in ES6
Let's say we have a class named Foo that I want to import. If I want to get the default export, I would do:
import Foo from './foo.js';
If I wanted a specific function inside the foo file, I would use the curly braces.
import { fooFunction } from './foo.js';
Note, this isn't a React feature, but ES6. Likely you are using babel to transpile your code from ES6 to ES5.
To create something similar in react. Lets take this following example.
someobject.js
const someobject = {
somefunc1: ()=>console.log("hello 1"),
somefunc2: ()=>console.log("hello 2")
}
export default someobject;
app.js
import someobject, { somefunc1, somefunc2 } from "./someobject";
someobject.somefunc1(); //hello 1
someobject.somefunc2(); //hello 2
somefunc1(); //hello 1
somefunc2(); //hello 2
export defaul
In the React module the default export is the React object and it also has a named export Component1, something like this:
// assuming React and Component are predefined
export default React
export Component
Coincidentally Component is also available on the React object, so it is not necessary to import separately, although some people prefer your approach. For example this is possible:
// MyComponent.js
import React from 'react'
class MyComponent extends React.Component {}
More information about ES6 module syntax can be found here.
1 Note that actually the React library does not have a named export Component as in the example above, however Component is a property on the default export and so due to the way that ES6 packages are transpiled by Babel, this becomes a named export, the behaviour then being as in the example above.
Import react will import the default react package, Component with braces then specifies a particular element of the React package. React by default will not need braces as it is the default import package.
import React, { Component } from "react";
Hope this helps
That is because the default export module in the react library is React, and there can be only one default export, even though you can export many other components, but only one can be default. Other components of the React library can then be destructured.
React is a module containing different methods, When using just React word, you import the whole module, so you can use React.Component (in this case dot notation reference to a method inside the module).
So if you need to import method? you will use braces, why?
because you import method between many methods in one module, So it's able to increase & decrease, so you can import {a, b, c, r, w, q} that's methods inside one class or one module, So you can see that if you using
import {Component} from 'react';
Now you can use Component word direct without dot reference like react.component.
So React module is exported by default, Here I need all the React module and I will use it with all methods, {Component} here exported by name, I need specific method from React library not all react library
and please check it too When should I use curly braces for ES6 import?
in the import import React, { Component } from "react"; we put the Component in braces because it is not the default export. however React is,... look at the following example
import React from "react";
export const Fun1 = () => {
return (
<React.Fragment>
<h1>this is fun 1</h1>
</React.Fragment>
);
};
export const Fun2 = () => {
return (
<React.Fragment>
<h1>this is fun 2</h1>
</React.Fragment>
);
};
const Fun3 = () => {
return (
<React.Fragment>
<h1>this is fun 3</h1>
</React.Fragment>
);
};
export default Fun3;
if we save the above file under example.js we can import the components in exmpample.js file as
import Fun3, {Fun1, Fun2} from "example";
therefore Fun3 is the default export and the other components Fun1 and Fun2 are not

JavaScript export 2 functions

I'm using React, Redux and now trying to include Material-UI. The Reduct and the Matrial-UI libs are showing example code that has an export at the end.
Redux:
export default connect(mapStateToProps, actions)(myComponent)
Material-UI:
export default withStyles(styles)(myComponent);
When I'm trying to bring both exports together, I have to get rid the default. So I thought it should look like this
This does not work:
export {
connect(mapStateToProps, actions)(myComponent),
withStyles(styles)(myComponent)
}
Error:
"Syntax error: Unexpected token, expected , (120:15)
export {connect(mapStateToProps, actions)(myComponent)}
^
This doesn't work:
I tried to name the function, but then the function wasn't called, for some reasons I don't know.
import * as myConnect from 'react-redux'
...
export const connect = myConnect.connect(mapStateToProps, actions)(View)
I don't know what is happening 'under the hood' so I'm stuck. Any help is appreciated :-)
EDIT
I haven't found a solution yet but I got around the problem. I split the component (myComponent) into an extra file. The design is event better like that, now it distinguishes between pure components and containers.
There is another solution that a lot of people will need at one point to build HOC (Higher order component). I will suggest using Recompose utility (if you are ok to add another package to your project). Here is a link to great article about it on medium.
So if I will be writing your code here is how I will write to build HOC:
import compose from 'recompose/compose';
//...your component code here
export default compose(withStyles(styles),
connect(mapStateToProps, actions))(myComponent);
{
connect(mapStateToProps, actions)(myComponent),
withStyles(styles)(myComponent)
}
This isn't a valid object; you're missing the keys.
{
myConnectedComponent: connect(mapStateToProps, actions)(myComponent),
myStyledComponent: withStyles(styles)(myComponent)
}
Make them named exports:
export const myConnect = connect(mapStateToProps, actions)(myComponent);
export const myStyles = withStyles(styles)(myComponent);
Then use named imports:
import {myConnect} from './yourscript';

Export multiple wrapper functions in Javascript ES6

I'm using react-komposer to wrap React components with a data fetching wrapper.
It is very basic and I'd want to wrap multiple components in Meteor. But I can't figure out what the export pattern is?
Here is what I have (and gives me an "Unexpected Token" error - probably obvious if you understand this well!):
// myContainer.jsx
import Component1 from './Component1.jsx';
import Component2 from './Component2.jsx';
function composer(props, onData) {
if (Meteor.subscribe('SingleTodoLists').ready()) {
const todoList = todoLists.find({}).fetch();
onData(null, { todoList });
}
}
export composeWithTracker(composer, Loading)(Component1);
export composeWithTracker(composer, Loading)(Component2);
And I'd like to import them like this:
import { Component1, Component2 } from './myContainer.jsx';
This wrapper syntax is not really clear for me, so I'm unsure about what to try. Playing with export default and other variations yielded no result so far.
If you don't use default exports, you need to name the things you export:
export const TrackedComponent1 = composeWithTracker(composer, Loading)(Component1);
export const TrackedComponent2 = composeWithTracker(composer, Loading)(Component2);
If you use default export instead you can omit the name, e.g.
export default composeWithTracker(composer, Loading)(Component1);
But you can only define one default export per module
See the documentation for the ES6 export syntax: https://developer.mozilla.org/en/docs/web/javascript/reference/statements/export
Update:
If you want to keep the original export names:
import _Component1 from './Component1.jsx';
import _Component2 from './Component2.jsx';
//... you code here
export composeWithTracker(composer, Loading)(_Component1);
export composeWithTracker(composer, Loading)(_Component2);
Because Component1.jsx uses a default exports, when you import it you can rename it as you want (e.g. _Component1, UntrackedComponent1, ...). Without a default export, you could have used import { Component1 } as _Component1 instead.

Categories

Resources