How to separate views from component in react-native - react-native

I am new to react native, The component looks very messy it has views, controller and styles everything in one file.
I want to organise these things in a separate file, like Write views (UI design) in separate files and styles in a separate file and want to import into components( How we do it in Angular projects)
Like this
UPDATE
#Component({
selector: 'app-outcome-ratio-popup',
templateUrl: './outcome-ratio-popup.component.html',
styleUrls: ['./outcome-ratio-popup.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class OutcomeRatioPopupComponent implements OnInit {
//i write logics here
}
in outcome-ratio-popup.component.html
<div>hello world <div> //i write view design code here
outcome-ratio-popup.component.scss
ul{
li{
margin-top: 10px; //i Write styles here
}
}

This is what i am currently following for my projects.
in root directory you can have folder 'app' which will have following structure
Edited
Suppose you have component name Header
Header
Index.js ( you can right component app logic here)
Style.js ( style for your component )
View.js ( view for your component )
I personally will not recommend above layout.
You can use following
Heder
Index.js ( you can right component app logic & view here)
Style.js ( style for your component )
Mostly in react-native we don’t kept view and logic in separate file because component file will contain very little amount of logic. And if your component is very huge you can try to break down component into small component. That will declutter your components.
if you can take look at this project and you will understand what i am trying to say

Related

vue multiple components in a single file

in vue documents I saw "Namespaced Components" in "script setup" guide it writes:
You can use component tags with dots like <Foo.Bar> to refer to components nested under object properties. This is useful when you import multiple components from a single file:
<script setup>
import * as Form from './form-components'
</script>
<template>
<Form.Input>
<Form.Label>label</Form.Label>
</Form.Input>
</template>
I wanted to know in this example what will the form-component look like, and what is the correct use case for such a component, does it have anything to do with "slot" or not.
In this case, form-components refers to a .js file that seems to be exporting single-file components (.vue).
form-components.js
export { default as Label } from './form-label.vue'
export { default as Input } from './form-input.vue'
You can then access these components via:
import * as Form from './form-components'
However, I recommend using a destructuring assignment methodology, as it is better interpreted by IDEs.
import { Input, Label } from './form-components'

Child components not rendering when referenced dynamically in composition API

I'm converting some components from vue 3's option API to the composition API. In this particular component I have two nested child components:
<script lang="ts" setup>
import ShiftOperation from "#/components/transformation-widgets/ShiftOperation.vue";
import RawJolt from "#/components/transformation-widgets/RawJolt.vue";
console.log([ShiftOperation, RawJolt])
...
From what I understand, if you're using the setup attribute in the script tag then all you have to do is import the component into a variable like I'm doing above and it should be available for the template without having to do anything else, like it's not like the old options api where you had to inject those components into the parent component.
Both components are imported successfully (confirmed by the console log:
When I'm rendering out this parent component I'm using the two child components to render out an array of data where I reference the children dynamically in the template based on information in each block of data that I'm iterating over:
<template>
<div class="renderer-wrapper">
<component
v-for="(block, index) in store.specBlocks"
v-bind:key="index"
:block="block"
:index="index"
:is="determineBlockComponent(block)"
#block-operation-updated="updateBlock"
>
</component>
</div>
</template>
// logic for determining the component to use:
export const determineBlockComponent = (block: JoltOperation) => {
switch (block.renderComponent) {
case 'shift':
return 'ShiftOperation'
default:
return 'RawJolt'
}
}
This worked fine in the options api version of it, but for some reason the components don't actually render. They show up in the elements tab:
But they don't show up in the view. I also added a created lifecycle hook into the child components that just console.log's out saying "created X", but those hooks don't fire.
Business logic wise nothing has changed, it's just been going from option api to composition api, so I'm assuming I'm missing some key detail.
Any ideas?
Your determineBlockComponent function should not return the string but the object of the component. Replace return 'ShiftOperation' with return ShiftOperation

How do I use SCSS variables with data-attributes in Vue JS and Bootstrap Vue

I'm trying to have a Dark Theme button on my application and change the whole theme in a click. It is already working but I wanted to find an easier way to accomplish that.
I have created a button in the navbar that sets a localStorage variable to "dark" or "light" on click. Upon loading the application, its store will read the localStorage and have it available to the whole application.
Excerpt from store.js:
state {
...
theme: localStorage.getItem('theme') || 'light',
...
}
In my application, if I want to change the theme to a breadcrumb, I would do:
<b-breadcrumb :data-theme="theme">
<b-breadcrumb-item active>Start</b-breadcrumb-item>
</b-breadcrumb>
import {mapState} from 'vuex'
export default {
...
computed: {
...mapState(['theme'])
}
}
and in the custom.scss file:
[data-theme="dark"] {
$breadcrumb-bg: $dark !important;
}
And it would have changed the whole component color.
This does NOT work.
However, this DOES:
.breadcrumb[data-theme="dark"] {
background-color: $dark !important;
}
My question is: Is there an easy way to change all components using data attributes and SCSS variables or do I have to mannually select classes and change the components I want?
Unfortunately it is not possible to use Sass variables in custom data attributes as I wanted because the specification for data attributes won't allow them. They expect a DOMString name, not a Sass variable.
https://html.spec.whatwg.org/multipage/dom.html#custom-data-attribute

Vue3 scoped classes are not applied for elements not declared in the template

I have a single-file vue3 component.
Its template looks like this.
<template>
<div ref="elements"></div>
</template>
I have scoped styles in the same file:
<style scoped>
.el {
color: red;
}
</style>
Now I want to add element in the script.
<script>
export default {
name: "App",
mounted() {
const div = this.$refs.elements;
const el = document.createElement("div");
el.setAttribute("class", "el");
el.innerText = "Hello World!";
div.appendChild(el);
},
};
</script>
The result shows that the element is not styled according to the class in the scoped styles.
Is there a way to apply styling to the elements added through script, while keeping styles in the scope?
After some research this seems to be an answer.
Vue scoped styling is the internal Vue feature. So, there should be a way to distinguish same class names on different components. Vue does it by adding a special id to each class name. You can find it by inspecting elements in the browser (e.g. data-v-a2c3afe).
When building a component, Vue processes its template and properly tracks only nodes you have declared for rendering there. It does not know anything it might get from somewhere. It actually makes sense and pushes you to write everything you expect to see in the template, so that it does not happen that you suddenly see something wrong in the DOM (especially if you are taking someone's code).
I have rewritten code, so that I still have scoped styles, but with no elements appending from the script and the code now allows to clearly see what is being rendered. This is probably the property of any framework - it makes you to stick to some patterns, so that everyone in the team/community knows what behavior to expect and writes more consistent code.

Angular 2 extending component - how to inherit styles

I want to extend component and override its html template only, but left all logic and styles. Unfortunately I see that all styles defined in parent component was not inherited. Is there the way to use styles of the component that was extended?
P.S. This is comoponent defined in node_modules, so I can edit source code.
If you want to bleed styles down to a component. You would put this on your target component.
#Component({
encapsulation: ViewEncapsulation.None
})