I would like to know if I can preset some props of components. I'm using Vuetify for this sample: Let's say you would want to customize the v-btn with some props. So the customized implementation would act as a child component because it still offers everything the parent component does but it implements some props directly.
You want to have some predefined buttons with a specific color so you could create your child button like
<template>
<v-btn color="primary"></v-btn>
</template>
but this would be bad because you still want to offer all the props and listeners the "real" button does. You just want to implement some props.
Is there a simple way I can achieve that?
You can import the VBtn component as a mixin and redefine the prop defaults.
import {VBtn} from 'vuetify/lib'
export default {
name : 'VBtnGreen',
mixins: [VBtn],
props: {
color : {
default : 'green'
}
}
}
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.
In Vue 3, I would like to display some of the properties from an external class inside of a Vue component, and have the component react to changes. The class is responsible for updating its own properties.
I was able to achieve this in Vue 2, by just creating a plain object which referenced the class properties I wanted to observe and putting that object into Vuex. From there, whenever the external class updated one of its properties, the vuex copy would also change.
In Vue 3, i'm using the reactive function from the composition api which I think creates a copy of the original object, which is probably why it doesn't work.
Is there any way to achieve this in Vue 3?
Here's a very simplified example of what I have tried. So I would want the count variable to refresh when it is updated by test.increment
<template>
<div>{{count}}</div>
</template>
<script>
import { defineComponent, reactive, ref } from 'vue';
let test = {
count: 1,
increment(){
this.count++;
}
};
setTimeout(()=>{test.increment()}, 2000);
export default defineComponent({
setup(){
return {
count: ref(test.count)
};
}
})
</script>
You can get, reference here in this StackBlitz Link
I have one folder file todoState.ts in models folder of project. This todoState.ts used for managing global state of application using custom hooks. I need to perform following tasks on global todoState.ts..
Add new State
Remove state
update state
here is code of todoState.ts.
import { useState, useEffect } from "react";
const todoState = (todo?, callback?) => {
const [todos, setTodos] = useState([todo]);
useEffect(()=>{
setTodos(todo);
},[])
return [{todos, setTodos}];
}
Now, I have Two user defined components which are dependent on globalState. which are 1. <TodoForm /> and <TodoListLineItem />
Both of above component is rendered inside index.tsx.
How can I manage global state from all the components including index.tsx , <TodoForm /> , <TodoListLineItem />. Here...
<TodoForm /> , is used to add to tasks to list.
<TodoListLineItem />, is used to display all added tasks from TodoForm component. when user hover over to each todo list item then user can able to remove perticular tasks-item from global management state.
Which one is best and reusable way to implement this global management state feature?
How one component changed state from A to B is reflected on related component by just manipulating global state object of application. If I put useState([]) into index.tsx then it will works well, But I want to manage state from TodoState.ts file. Thank You.
export default todoState;
Finally , I found and learned New concepts for React-Context API. You can checkout here StackBlitz Link
To manage global states React provides context-api. Use only when you have multiple level of component properties pass down in component tree from Top to bottom. I used very small example to understand context api for my different use-case.
First of all we need to use two context..
createContext [ used to create global state context ]
useContext [ used to get states from context from child component ].
To work with Context I created one <context.Provider> component. and all state management tasks are done with only this component level only. all child component just send events of what to do. and global context of provider component changes accordingly.
firstly, Create context..
export interface ItodoContext{
todoState? : Itodo[];
addNewTodoState?: (state?: string) => void;
removeTodoItemByIndex? : (index?: number) => void;
}
export const todoContext = createContext<ItodoContext[]>([{}]);
As, I am using React-Typescript functional component, as per Interface of context i defined all tasks of states. I passed all TodoState, function to manipulate TodoState like addNewTodoState, removeTodoItemByIndex.
then create Provider of context..
const allTodoStates = {
todoState,
addNewTodoState,
removeTodoItemByIndex
}
return(
<todoContext.Provider value = { [allTodoStates]}>
{props.children}
</todoContext.Provider>
)
Then I set Provider as parent component in tree in index.tsx component like this..
const App: FC = () => {
return (
<div className="h-100 w-100">
<TodoStateProvider>
<Navbar />
<div className="container">
<TodoForm />
<TodoListLineItem />
</div>
</TodoStateProvider>
</div>
);
}
See above all components now child of <TodoStateProvider> parent component.
When I need to add new state to context is inside <TodoForm> and how we can add state is as below code...
const [{addNewTodoState}] = useContext(todoContext);
const sendTodoItem = (e) => {
addNewTodoState(todoInput.trim());
}
and so on.. provider component has value property, and we can get those properties from child using useContext() hook. as we used above. See full working demo I have attached in above StackBlitz Link.
To make e2e testing easier I would like to add to each react component data-component= attribute with component name. I would like to have it done "automatically" (without adjusting render() functions everywhere).
Anyone knows how to do it reliably for both class and function based components?
Component name is set via static property displayName for each component. You need to set it manually.
Create hoc (higher order component), to wrap component with div (or any other html tag) which will have required attribute.
const withComponentName(WrappedComponent) => {
const displayName = WrappedComponent.displayName || WrappedComponent.name || 'UnnamedComponent';
return props => (
<div data-component={displayName}><WrappedComponent {...props} /><div>
)
}
Wrap all component export statements with created hoc.
export default withComponentName(YourShinyComponent)
Another option is to use this Webpack plugin to do it for you:
https://github.com/lemonmade/babel-plugin-react-component-data-attribute
If you're using create-react-app:
If you've ejected already then just follow the docs on the plugin's page ☝️
However, if you have not ejected already, then you can use either of these solutions to customize your build for a create-react-app project:
https://github.com/arackaf/customize-cra
https://github.com/timarney/react-app-rewired/
In react I can arbitrarily pass props down like so:
function SomeComponent(props) {
const {takeOutProp, ...restOfProps} = props;
return <div {...restOfProps}/>;
}
How can I do the same thing in Angular?
--
More specifically, I want to write a custom dropdown component and pass props down to a select box.
As opposed to React components, Angular components aren't recompiled on input changes and use #Input property decorators to enable change detection. All properties that are expected to be passed should be explicitly defined as component inputs.
There are no better options than this one for custom select component. It's possible to read static attributes from current component element and set them on nested component element, but this won't set up bindings.
As for React recipe for deep props in wrapped components:
const Baz = props => <p>{props.baz}</p>;
const Bar = props => <Baz {...props} />;
const Foo = props => <Bar {...props} />;
This is usually handled by Angular DI and a hierarchy of injectors. A provider can be defined on respective injector in order to make data and behaviour available to nested components.
Actually it is not the answer on your question but perhaps it helps you.
You can add one custom directive with all params you need.
import { Directive, ElementRef } from '#angular/core';
#Directive({
selector: '[defaultConfig]'
})
export class DefaultDropdownConfigDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
// your default config
}
}
<my-dropdown defaultConfig></my-dropdown>
For more details you can read this