In a page I need to have multiple modals, and I did this
import ApproveModal from '~/components/common/modal'
import RejectModal from '~/components/common/modal'
this.setState({ openApproveModal: true })
{openApproveModal && <ApproveModal />
this.setState({ openRejectModal: true })
{openRejectModal && <RejectModal />
Not sure this is the correct way to do it but I saw possible of having duplicated codes, what if I have 3-4 actions, I need to import 4 confirmation modals?
In your modal component, just export multiple instances of various modals:
export { ApproveModal, DeclineModal };
Then just import them using the very useful destructuring pattern (more here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment):
import { ApproveModal, DeclineModal } from '~/components/common/modal';
Related
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.
I have a react-native app that contains two applications in it. These two parts have their own UI and state. When users open up the app want to sign up, they can select how they wanna use this application.
I like to encapsulate state these two parts from each other.
My idea was to have two providers and render them conditionally, but don't know this is a good practice and have any edge cases or not.
const rule = 'first' // or 'second'
rule === 'first' ?
<Provider store={firstStore}>
// first app related screens
</Provider>
:
<Provider store={secondStore}>
// second app related screens
</Provider>
Who can I encapsulate the state for these two parts perfectly?
Separating UI and Data is a good idea. You can't have two providers though, you need to put these into 2 separate reducers. So, you can have something like this (code is just a snipped example, you'd replace with your own of course).
import { combineReducers } from 'redux';
import carousels from './dataCarouselsReducer';
import filterIntents from './filterIntents';
import generatedImages from './generatedImages';
import indexing from './indexing';
import { nlpIntentsReducer } from './nlpIntents';
import nullSpaceData from './nullSpaceData';
import { searchReducer } from './search';
import similarityIntents from './similarityFilterIntents';
import uiCarouselsReducer from './uiCarouselsReducer';
import user from './user';
import workflows from './workflows';
const rootReducer = combineReducers({
data: {
user,
search: searchReducer,
nullSpaceData,
similarityIntents,
carousels,
indexing,
generatedImages,
workflows,
},
ui: {
filterIntents,
nlpIntents: nlpIntentsReducer,
uiCarouselsReducer,
},
});
export default rootReducer;
I am very new to Vue and I have read an article or two about it (probably vaguely).
Also, Since I have some understanding of react, I tend to assume certain things to work the same way (but probably they do not)
Anyway, I just started with Quasar and was going through the Quasar boilerplate code
In the myLayout.vue file, I see being used inside my template
<template>
<q-layout view="lHh Lpr lFf">
<q-layout-header>
<q-toolbar
color="negative"
>
<q-btn
flat
dense
round
#click="leftDrawerOpen = !leftDrawerOpen"
aria-label="Menu"
>
<q-icon name="menu" />
</q-btn>
based on my vaguely understanding, I thought for every component we are using to whom we need to pass props we need to import it as well but unfortunately I can't see it in my import-script area
<script>
import { openURL } from 'quasar'
export default {
name: 'MyLayout',
data () {
return {
leftDrawerOpen: this.$q.platform.is.desktop
}
},
methods: {
openURL
}
}
</script>
I would've thought the script to be something like
<script>
import { openURL } from 'quasar'
import {q-icon} from "quasar"
or at least something like that but here we only have
import { openURL } from 'quasar'
Also, Even if we remove the above snippet, our boilerplate app looks to be working fine so here are my two questions
Question 1: What is the use of import { openURL } from 'quasar' (like what it does)
Question 2: How can template contain <quasar-icon> or <quasar-whatever> without even importing it in script tag?
How can template contain <quasar-icon> or <quasar-whatever> without even importing it in script tag?
There are two ways to import components. The first way (which I recommend, and being most similar to React) is to import the component and add it to the components option inside the component that you want to use it within.
App.vue
<div>
<my-component/>
</div>
import MyComponent from 'my-component'
export default {
components: {
MyComponent
}
}
The second way is to import it globally for use within any Vue component in your app. You need only do this once in the entry script of your app. This is what Quasar is doing.
main.js
import Vue from 'vue'
import MyComponent from 'my-component'
Vue.component('my-component', MyComponent)
What is the use of import { openURL } from 'quasar' (like what it does)
I'm not familiar with Quasar, so I can't give you a specific answer here (I don't know what openURL does). You should check the Quasar docs.
openURL is being used as a method here. Perhaps it is being called from somewhere in the template (which you have excluded from the question).
A1) Import statement is 1 way (es6) way to split your code into different files and then import functions/objects/vars from other files or npm modules see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
A2) Vue allows 2 mechanisms to register components. Global and local. Globally registered components does not have to be imported and registered in every component before use (in template or render fn). See URL from comment above https://v2.vuejs.org/v2/guide/components-registration.html#Global-Registration
I am working a reactjs file that uses the react-ace library. Currently my code looks like this
import React, { Component } from 'react';
import 'brace/mode/html';
import 'brace/theme/monokai';
import AceEditor from 'react-ace';
class AceHTML extends Component {
render () {
return (
<AceEditor
mode="html"
theme="monokai"
name="Sample"
showPrintMargin={false}
wrapEnabled={true}
value={this.state.value}
editorProps={{
$blockScrolling: true
}} />
);
}
}
However I am trying to figure out a way to make it more generic. So I could say something like <Ace mode="javascript" /> and then in the component would import brace/mode/javascript instead of brace/mode/html
So my question is: What is the best way to load a library instead of using import?
PS: The reason I specifically pointed out that I am using react is because I am using create-react-app to create the application.
import all assets you want to use and you will be able to make changes as you please.
If you don't want to import all assets initially, you can use dynamic imports and load required chunks when a user requests a different editor configuration:
async changeTheme(theme) {
await import("brace/theme/" + theme)
this.setState({ theme });
}
async changeMode(mode) {
await import("brace/mode/" + mode)
this.setState({ mode });
}
live demo:
https://stackblitz.com/edit/react-nzivmp?file=index.js (without dynamic imports since they don't work on stackblitz)
import React from 'react';
import { render } from 'react-dom';
import brace from 'brace';
import AceEditor from 'react-ace';
import 'brace/mode/html';
import 'brace/mode/javascript';
import 'brace/theme/monokai';
import 'brace/theme/github';
function onChange(newValue) {
console.log('change',newValue);
}
// Render editor
export default ({mode, theme}) => (
<AceEditor
mode={mode}
theme={theme}
onChange={onChange}
name="UNIQUE_ID_OF_DIV"
editorProps={{$blockScrolling: true}}
/>
);
Importing libs isn't job for React. Webpack decides what to load to a bundle file. If you want to use any options based on props you'll need to import both anyway.
If there are large files and you don't want to load both of them for your application's user you can fetch them via AJAX request.
I am using React-Navigation where I am using functionality of custom drawer by using contentComponent of React-Navigation.
const DrawerNavigation = DrawerNavigator({
DrawerStack: { screen: DrawerStack }
}, {
contentComponent: DrawerComponent,
drawerWidth: 300
})
Here DrawerComponent is my custom navigation drawer where I have used custom navigation items like username, profile picture, email address and other menus.
Now whenever user updates their profile I want to refresh my DrawerComponent, I am not able to find any way to do it. Can anybody suggest me a good way to implement this?
Couple of options here, and all are tight to how you want to achieve your state management.
First, one solution would be to have the your user state in the component creating the DrawerNavigator, and pass it down to your custom drawer component. This presents the disadvantage of having to recreate your navigator on state change and create a blink. I do not advice to use this solution but it's worth mentioning as a possibility.
You could also use a React Context, have your user state in a top level component, create a provider passing it the user as the value and make your drawer a consumer of this context. This way, every time the user changes your drawer component would re-render.
What I use personally is Redux to connect my Drawer directly to my global state. It involves a bit of setup but it's worth it in the end. A root component could look like this:
import React from 'react'
import { Provider } from 'react-redux'
export default () => (
<Provider store={store}>
<App />
</Provider>
)
Where store is the result of:
import { createStore, combineReducers } from 'redux'
import reducers from './reducers'
const store = createStore(combineReducers(reducers))
Your reducers are going to be the state of your app, and one would be dedicated to your user data.
Then your Drawer component could be:
import React, { Component } from 'react'
import { View, Text } from 'react-native'
import { connect } from 'react-redux'
#connect(({ user }) => ({ user }))
class Drawer extends Component {
render () {
const { user } = this.props
return (
<View>
<Text>My name is {user.name}</Text>
</View>
)
}
}
export default Drawer
Now, every time you change your user reducer, this Drawer component will re-render.
There is a few things your should know about Redux, so you should probably read up a bit the Getting Started docs.
I know it is a old question now but you can do this by importing the code like
import DrawerView from '../Drawer/Drawer'
contentComponent: DrawerView
then in the DrawerView file
class DrawerView extends Component {
render(){
return(
//Do your stuff here
)
}
}
export default DrawerView;
for more info please visit this link and thank to Kakul Gupta for this https://codeburst.io/custom-drawer-using-react-navigation-80abbab489f7
The easiest way to change menus without using redux is, using createSwitchNavigator.
https://reactnavigation.org/docs/en/auth-flow.html