Extending namespaced JS imports - javascript

This is a general ES6 question, but I've encountered it in the context of React Native. The basic problem is that I want to override some components that I usually import from the 'react-native' module with my own components. My method for doing this looks like the following:
Instead of requiring components with import { Text, View, etc } from 'react-native'
require them like this: import { Text, View, etc } from './ui_components'
where ui_components.js looks something like:
export * from 'react-native'
The issue is, how do I add my own components to this export? Ideally I'd be able to add them in ui_components.js by doing something like this:
import * as RN from 'react-native'
RN.Text = myTextComponent
RN.View = myViewComponent
export * from RN
But this doesn't quite work. Any ideas?

You need to import React Native's component and reexport it, with or without extensions from your side - it's up to you.
But remember - don't ever override React's internals (or any other's internals). Components are composable, yay!
For example, here, I am creating my custom Text component cause I want all texts in my app to be red by default. Also I want it to be configurable if I need different color for title/subtitle/whatever...
import React from 'react';
import { Text as NativeText } from 'react-native';
export default function Text({ style, ...props}) {
return <NativeText style={[ { color: 'red' }, style]} {...props} />
}
Got an idea?
Good, now to folder structure...
ui_components
| - index.js
| - Text.js
// Text.js
// See example above...
// index.js
export { default as Text } from './Text';
// In your app
import { Text } from './ui_components';

Related

Component Palette Custom Hook

I am fairly new to React and still wrapping my head around custom-hooks. I cam across a code where a custom hook was created to handle the component imports.
useComponentPalette.js
import {TodoEditor} from './components/TodoEditor'
import {TodoItem} from './components/TodoItem'
import {TodoList} from './components/TodoList'
import {CheckBox} from './components/CheckBox'
const defaultComponents = {
TodoEditor,
TodoItem,
TodoList,
CheckBox
}
export function useComponentPalette(){
return defaultComponents
}
And then in order to use the hook,
const {TodoItem, TodoList, Checkbox } = useComponentPalette()
My Question :- Does this approach provides any advantage over the regular imports in the component ? or this is an anti-pattern ?
How I usually import the components is as follows
import {TodoEditor} from './components/TodoEditor'
import {TodoItem} from './components/TodoItem'
import {TodoList} from './components/TodoList'
import {CheckBox} from './components/CheckBox'
function App(){
return(
<>
<TodoList/>
</>
)
}
It's not a good idea to use react hooks like this you can get the same result without react hook
// first file name.js
import {TodoEditor} from './components/TodoEditor'
import {TodoItem} from './components/TodoItem'
import {TodoList} from './components/TodoList'
import {CheckBox} from './components/CheckBox'
export default {
TodoEditor,
TodoItem,
TodoList,
CheckBox
}
//component file
import * as Component form 'first file name';
//<Component.TodoEditor/>
//or
import {TodoEditor} form 'first file name';
The way that I use react-hooks is for making my code more dry and increase it's readability, so react-hooks is not good fit for this kind of usage.
Hi #Sachin,
In my option, React JS use hook to manage reuse stateful logic between components. In other word, Hooks do well to encapsulating state and share logic. If you want to do some stateful logic or condition base logic with these components, then it's fine with that. But if you are using just without condition in the given components. Then, This Is useless for making the custom hook. You can do that without a custom hook in a simpler way.
Here is a simple way to do that:-
In components folder. I create index file, this is the entry point of all my exporting components
In that file. I export all my components, as you can see.
I use that components like this. It much better way. In my option.
import { Header, Footer, Sider } from "./components"
before using react custom hooks, we should be aware of the rationale behind it.
Customs hooks functionality was provided to reuse stateful logic. If logic doesn't require any state, we will use simple functions and if it is about components only there there are different patterns for making code general and scaleable.
So, there is no usage of custom hook in above case at all. For me, I would go with the following code for above scenario:
// components/index.tsx
import {Todo} from './todo'
import {CheckBox} from './components/CheckBox'
export {
Todo,
CheckBox
}
// componentns/todo/index.tsx
import {Editor} from './Editor'
import {Item} from './Item'
import {List} from './List'
const Todo = {
Editor,
Item,
List
}
export default Todo;
and usage will be like
import { Checkbox, Todo } from "components"
...
<Checkbox ... />
<Todo.List ...>
<Todo.Item ... >
</Todo.Editor ... />
</Todo.Item ... >
</Todo.List>
...
P.S Usage can be different based upon the logic of components, just giving an hint how we can patterns to serve our purpose.
Hope it helps.

Most efficient way of importing files from children folders?

I have a parent directory that contains children directories, where each contains an SVG component and I only need to import some of them. I'm currently importing all the components I need by doing this:
import FacebookIcon from 'project/icons/Facebook';
import TwitterIcon from 'project/icons/Twitter';
import DiscordIcon from 'project/icons/Discord';
import MediumIcon from 'project/icons/Medium';
import YoutubeIcon from 'project/icons/Youtube';
However this seems very verbose. Is there a less verbose way of doing this?
I thought about destructuring, but I wasn't sure how to do this since each file is in a different folder.
Typically, you want to import similar components from a single source (you will get auto-complete too):
import {
FacebookIcon,
TwitterIcon,
DiscordIcon,
DiscordIcon,
MediumIcon,
YoutubeIcon,
} from "project/icons";
// Usage
<FacebookIcon/>
// Same
import Icons from './project/icons';
// Usage
const Icon = Icons.FacebookIcon;
<Icon/>
To achieve this, create index.js file in project/icons and make named export for each of the components.
export { default as FacebookIcon } from "./FacebookIcon";
...

Create custom stylesheet through javascript

I was putting together a react-native app and noticed one glaring annoyance. Every time I wanted to use a theme when creating a stylesheet, I had to import the theme from an external file to use it.
Something like this
import { StyleSheet } from 'react-native'
import { theme } from 'path-to-theme/theme.js'
const styles = StyleSheet.create({
container: {
backgroundColor: theme.background
}
})
Coming from a React background, what I was wanting to do is get the theme provided to the constructor of sorts, so I don't have to do an import every time. Kind of like material-ui does it
import { StyleSheet } from 'custom-stylesheet-path/stylesheet.js'
const styles = StyleSheet.create(theme => {
container: {
backgroundColor: theme.background
}
})
But I'm not sure how to go about the implementation. Especially providing the theme to the stylesheet constructor. Anybody got any experience with this? Even just a starting point
NativeBase is able to implement themes in react native. The way that it does it, is to create the standard set of react native components and then require that you import those elements from native-base rather than react-native.
Example:
import { Label } from 'native-base'
Rather than:
import { Text } from 'react-native'

Javascript how to export modules inside groups

I´ve several React components as a library in folder ux (some itens below):
import MessageBar from "./atoms/MessageBar/MessageBar";
import Spinner from "./atoms/Spinner/Spinner";
import Button from "./atoms/Button/Button";
import AccordionHeader from "./molecules/AccordionHeader/AccordionHeader";
import AutocompleteList from "./molecules/AutocompleteList/AutocompleteList";
import ButtonGroup from "./molecules/ButtonGroup/ButtonGroup";
import LoginPanel from "./organisms/LoginPanel/LoginPanel";
import WelcomePanel from "./organisms/WelcomePanel/WelcomePanel";
I wish to export these objects so that it can be imported from its group:
import LoginPanel from "ux.organisms";
Or
import Button from "ux/atoms";
Or whatever.
The idea is that you are getting the element from an specific group inside ux library.
What is the suggested way to export all of those components, organized into groups (atoms, molecules, organisms, etc.) ?
PS:
a. I don´t wnat to change the component name (ButtomAtom, etc...)
b. The result will be a npm library to be imported by other projects. So, this code will reside on my ux/index.js file.
Then make a index.js file at ux/atoms/ and fill it with:
import MessageBar from "./MessageBar/MessageBar";
import Spinner from "./Spinner/Spinner";
import Button from "./Button/Button";
//...
export { MessageBar, Spinner, Button };
So now one can do:
import { MessageBar } from "ux/atoms";
Or if you need every submodule:
import * as Atoms from "ux/atoms";

Webpack resolve a directory for import paths (goCardless as a boiletplate)

Currently a typical component will look like the below code. Note that using the paths to the file has become problematic and ugly. Moving a file causes massive issues with updating paths across multiple components.
This truly takes away from the component based experience when a path change can break everything and cause mass find and replace of paths.
In an ideal world the displayName would be the import reference and searched for within the directory.
'use strict';
//libs
import React from 'react';
//components
import TopFeatures from '../../headphones/subcomponents/top-features';
import Prices from './prices';
import Image from '../../layout/image';
import InlineRatingElement from '../../reviews/rating';
//helpers
import { getImageUrl } from '../../helpers/app/image';
import { initiateInlineRatings } from '../../helpers/app/inline-ratings';
export default class HDOverview extends React.Component {
displayName = 'HDOverview'
static propTypes = {
vendor: React.PropTypes.string.isRequired
}
constructor(props) {
super(props);
}
render() {
return (
<div>
JSX
</div>
);
}
}
I am looking to do something like this:
import TopFeatures from 'TopFeatures';//TopFeatures is the displayName
import Prices from 'Prices'; //Prices is the displayName etc.
import Image from 'Image';
import InlineRatingElement from 'InlineRatingElement';
//helpers
import { getImageUrl } from 'ImageHelper';
import { initiateInlineRatings } from 'InlineRatingHelper';
Webpack has a great tutorial on resolve aliases here: http://xabikos.com/javascript%20module%20bundler/javascript%20dependencies%20management/2015/10/03/webpack-aliases-and-relative-paths.html
However this insinuates that the path to the component would need to be logged in one place - in an ideal world there would be a way to dynamically check paths / directories to find the displayName that matches. Note that we have 200 components, so manually creating that list is do-able but sizable.
Having looked around I have seen people using
require("components!/layout/image")
however we would like to stick to the import technique and not go back to require.
Any suggestions or advice are greatly appreciated.
I think that this is, unfortunately, a limitation of node, npm.
There are workarounds to get absolute/mapped paths to work in npm but all of these have drawbacks: https://gist.github.com/branneman/8048520
Another option is individual npm packages for each component, but this adds a lot of overhead.

Categories