Dynamic import base on props name in react
import { a, b, c } from 'some-package/theme' // should not import everything here
const MyComp = ({ theme, ...other }) => {
console.log(theme) //can be a, b, c, d, e etc
return(<MyCompInner />)
}
export default MyComp
How can I do dynamic import from 'some-package/theme' ? the prop of theme can be a, b, c and more. Theme props is the option, but I have to import the value from 'some-package/theme' before I supply it to <MyCompInner />
You could use require() for this. Unlike import which has to be at the top, you can use require() anywhere in your code.
const MyComp = ({ theme, ...other }) => {
const t = require('some-package/theme/' + theme);
return(<MyCompInner theme={t} />)
}
export default MyComp
Related
When I implement a simple React component with Mui's withStyles HOC, I have to use the keyword "default" when exporting the component. Why can't I use the HOC in the return statement within the functional component?
Is there something about Js or ReactJs that I'm missing?
Since I am forced to export this component as default, I lose the possibility to use the named import functionality, without using another import/export layer in between.
Below is the current working code:
// Card.js
import React from "react";
import {
Card,
withStyles
} from "#material-ui/core";
const styles = theme => ({
card: {
margin: theme.spacing(2)
}
});
function CustomCard(props) {
const {classes} = props;
return (
<Card className={classes.card}>
Export me without being the default component.
</Card>
);
}
export default withStyles(styles)(MediaCard);
// Elsewhere.js
import CustomCard from "Card";
...
But i'd rather write something like this:
// Cards.js
import React from "react";
import {
Card,
withStyles
} from "#material-ui/core";
const styles = theme =\> ({
card: {
margin: theme.spacing(2)
},
anotherCard: {
margin: theme.spacing(4)
}
});
export function CustomCard(props) {
const {classes} = props;
return withStyles(styles)(
<Card className={classes.card}>
Jeah. I'm not the default component.
</Card>
);
}
export function AnotherCard(props) {
const {classes} = props;
return withStyles(styles)(
<Card className={classes.anotherCard}>
Jeah. I'm not the default component either.
</Card>
);
}
// Elsewhere.js
import { CustomCard, AnotherCard } from "Cards";
...
You can do it the way you want to but you to change the way you define your components. The technical reason is that all exports except default need to be named, otherwise you can't import them and know what's what. Since withStyles() returns a statement and not a named variable/function you can't export it without a name.
export const AnotherCard = withStyles(styles)((props) => {
const {classes} = props;
return (
<Card className={classes.anotherCard}>
Jeah. I'm not the default component either.
</Card>
);
});
The downside of this is of course now your components aren't hoisted.
I would like to use this form often used in React or in this example react-redux
import redux, { useSelector, useDispatch } from 'react-redux';
So I tried the obvious:
I created an export file:
const exp = {};
exp.a = 'a-1';
exp.b = 'b-1';
export default exp;
And a file to import it:
import {a, b} from './40-export.js'; // this does not work
// import test from './40-export.js'; // this works
// const {a, b} = test; // this works
You need to both have an export default and named exports. Make standalone a and b variables that you export, and that you assign to properties of the default export object.
export const a = 'a-1';
export const b = 'b-1';
export const exp = { a, b }; // if you want this to be a named export too
export default exp;
export const a = 2
export const b = 3
export default const c = 3
Then
import c , {a, b} from "your/file"
Note the use of {...} for named imports and the lack of it for default exports.
This my main class
import React, { Component } from 'react';
import { withStyles } from '#material-ui/core/styles';
import styles from './FoodStyles';
class Food extends Component {
render () {
return (
<div>
<h2 className="header">Food</h2>
</div>
)
}
}
export default withStyles(styles) (Food);
And this is my style class called FoodStyles.js
const styles = theme => ({
header: {
backgroundColor: 'red'
},
});
export default styles;
They both are in the same folder but still styles cannot be accessed
This could be the solution to your problem: (You need destructuring as done in line 7 for your styles to be used in your file.) With React, which fully embraces the ES6 syntax, destructuring adds a slew of benefits to improving your code.
Food.js:
import React, { Component } from 'react';
import { withStyles } from '#material-ui/core/styles';
import styles from './styles';
class Food extends Component {
render () {
const { classes } = this.props;
return (
<div>
<h2 className={classes.header}>Food</h2>
</div>
)
}
}
export default withStyles(styles)(Food);
styles.js:
const styles = theme => ({
header: {
backgroundColor: 'red'
},
});
export default styles;
Result:
Reasons to destructure:
1. Improves readability:
This is a huge upside in React when you’re passing down props. Once you take the time to destructure your props, you can get rid of props / this.props in front of each prop.
2. Shorter lines of code:
Insead of:
var object = { one: 1, two: 2, three: 3 }
var one = object.one;
var two = object.two;
var three = object.three
console.log(one, two, three) // prints 1, 2, 3
We can write:
let object = { one: 1, two: 2, three: 3 }
let { one, two, three } = object;
console.log(one, two, three) // prints 1, 2, 3
3. Syntactic sugar:
It makes code look nicer, more succinct, and like someone who knows what they’re doing wrote it.
I would just use makeStyles instead of withStyles.
App.jsx
import Food from "./Food";
const App = () => {
return (
<div className="App">
<Food />
</div>
);
};
export default App;
Food.jsx
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import styles from "./FoodStyles";
const useStyles = makeStyles(styles);
const Food = () => {
const classes = useStyles();
return (
<div>
<h2 className={classes.header}>Food</h2>
</div>
);
};
export default Food;
FoodStyles.js
const styles = (theme) => ({
header: {
backgroundColor: "red"
}
});
export default styles;
I am trying to make use of Material-UI v1 with stajuan's Redux-Saga Login template shown here. So, I want to merge the export default thing of those two, in other words combine two functions for exporting the default class:
import React, {Component} from 'react';
import { connect } from 'react-redux';
import { withStyles, createStyleSheet } from 'material-ui/styles';
// Redux
function select (state) {
return {
data: state
}
}
// Material UI v1
const styleSheet = createStyleSheet(theme => ({
// ...
}));
// Class to be exported
class Login extends Component {
// ...
render () {
// ...
}
}
// H O W T O M E R G E T H O S E ? ? ?
// export default connect(select)(Login);
// export default withStyles(styleSheet)(Login);
The last two commented-out lines of the code above are the statements to be combined in my case.
you need to install npm install recompose or yarn add recompose
and on your export section
export default compose(
withStyles(styles, {
name: 'App',
}),
connect(),
)(AppFrame);
or you can do:
export default withStyles(styles)(connect(select)(Cart));
You will be able to access with the key
this.props.domain
Add below line to export your class
const mapStateToProps = state => {
return { domain : 'yourdomain.com'
}
}
export default withStyles(styles)(connect(mapStateToProps)(Login));
How can I export a stateless pure dumb component?
If I use class this works:
import React, { Component } from 'react';
export default class Header extends Component {
render(){
return <pre>Header</pre>
}
}
However if I use a pure function I cannot get it to work.
import React, { Component } from 'react';
export default const Header = () => {
return <pre>Header</pre>
}
Am I missing something basic?
ES6 doesn't allow export default const. You must declare the constant first then export it:
const Header = () => {
return <pre>Header</pre>
};
export default Header;
This constraint exists to avoid writting export default a, b, c; that is forbidden: only one variable can be exported as default
Just as a side note. You could technically export default without declaring a variable first.
export default () => (
<pre>Header</pre>
)
you can do it in two ways
const ComponentA = props => {
return <div>{props.header}</div>;
};
export default ComponentA;
2)
export const ComponentA = props => {
return <div>{props.header}</div>;
};
if we use default to export then we import like this
import ComponentA from '../shared/componentA'
if we don't use default to export then we import like this
import { ComponentA } from '../shared/componentA'
You can also use a function declaration instead of assignment:
export default function Header() {
return <pre>Header</pre>
}
In your example, you already use curly brackets and return so this is apparently matching with your needs with no compromise.