Trying to map out unique react components - javascript

I am trying to map out data into a react component, but I only want unique instead of duplicate components to render to the page. I was researching on how to use the filter, Set, and unique methods was having a hard time figuring out how to work a React component into the syntax
so far....
import React, { useContext } from 'react'
import Tag from '../components/Tag'
import feedbackContext from '../utils/FeedbackContext'
const Tags = () =>{
const data = useContext(feedbackContext)
return(
<>
{
data.map((tag,id) =>(
<Tag key ={id} category={tag.category}/>
))
}
</>
)
}
export default Tags
In the code snippet above it renders all tags from the json file which results to duplicates components being rendered. I was looking up the unique, filter and Set methods, but couldn't quite grasp how to use this in the case of rendering unique components. Has Anyone ever done this before?
Update, let me rephrase what I meant from above, it the snippet below, I simply want just one of each category name appearing. It's technically not duplicating:
<div class="filter">
<div class="category_type">enhancement</div>
<div class="category_type">feature</div>
<div class="category_type">feature</div>
<div class="category_type">enhancement</div>
<div class="category_type">feature</div>
<div class="category_type">bug</div>
<div class="category_type">feature</div>
<div class="category_type">feature</div>
<div class="category_type">feature</div>
<div class="category_type">feature</div>
<div class="category_type">bug</div>
<div class="category_type">enhancement</div>
</div>

Related

React.js NavBar: Is it possible to reference a different component's markup? (Trying to create a navbar that references to components in one route)

Basically I'm trying to make a navbar for a personal website application in which the navbar references content (About/Skills, etc.) all on single page (route). When making the navbar, I can easily reference markup with ids/classes BUT I would have to put all the html in one file.
I noticed that if I were to separate each content into its own react file (About.jsx, Skills.jsx, etc.) and import them, there didn't seem to be a way for me to reference the react component's markup.
I also noticed with react router, this wasn't feasible because each component would be on a separate route (which I don't want) rather than on a single route.
This is my current navbar file below; How exactly Can I import and reference the markup of the separate components?
import React from 'react';
import "../Styles/NavBar.scss";
import About from "./About.jsx"; (Not used)
import Skills from "./Skills.jsx"; (Not Used)
import Projects from "./Projects.jsx"; (Not used)
const NavBar = () => (
<div class="MainDivWrapper">
<div class="NavBarDiv">
<h1 class="NavBarH1">NavBar</h1>
<br/>
<nav>
About
Skills
Projects
</nav>
{/* <div id="AboutDiv">
<h1>About Me</h1>
<span>Just some text</span>
</div>
<div id="SkillsDiv">
<h1>Skills</h1>
<span>Just some text</span>
</div>
<div id="ProjectssDiv">
<h1>Projects</h1>
<span>Just some text</span>
</div> */}
</div>
<hr class="HeaderDivider"/>
</div>
)
You reference a JSX import like that:
/* Component have to start with a capital letter. file name can be anything (usually is the same as component) */
import MyComponent from "./MyComponent"
export default function MyApp() {
return (
<div>
/* other html/components here */
<MyComponent /> // selfing close tag
/* or */
<MyComponent> // with `children`
some content
</MyComponent>
</div>
)
}
Here is a codesandbox implementation of your code: https://codesandbox.io/s/stack-reactjs-navbar-is-it-possible-to-reference-a-different-components-markup-64oic?file=/src/App.js

passing props as classNames in next.js

I am trying to have the header of each of my app's pages change color based on the current page. How I am trying to achieve this:
<Header className="headerBitcoin"></Header>
What I want is the be able to have the header component present on all 4 pages, and then just change the className to another prop to change the background but not anything else.
And the header component itself
import styles from "../../styles/Home.module.css";
export default function Header(props) {
return (
<div >
<div className={props.className}>aaaaa</div>
<div className={styles.row}>
<div className={styles.tab}>a</div>
<div className={styles.tab}>a</div>
<div className={styles.tab}>a</div>
<div className={styles.tab}>a</div>
</div>{" "}
</div>
);
}
At the moment the styles for the tabs and row are working but the header is not getting its style applied.
I checked the console and found the header is getting the className headerBitcoin passed to it, however the row beneath it has the className of "Home_row__88lPM"
This is my first time working with next.js, and I know I am doing something wrong because this works in React. Any help would be appreciated.
don't do this:
<div className={props.className}>aaaaa</div>
try this instead:
<div className={styles[props.className]}>aaaaa</div>
I think this should works
I assume it's not being applied because you have the headerBitcoin styles defined in your CSS module.
If you want to apply a class that way (className="headerBitcoin"), you need to define the class in your global CSS instead.
If you meant to use the headerBitcoin defined in Home.module.css, then you'll want to change the className to use the scoped styles.
import styles from "../../styles/Home.module.css";
export default function Header(props) {
return (
<div >
<div className={styles[props.className]}>aaaaa</div>
// ...
</div>
);
}

Render external element inside Vue component

I have an external div that I need to render inside my Vue app. I'm trying to use a slot, like but that's a no go as nothing renders.
Any ideas?
Goal is to have HTML like this (Vue mounts on #app):
<div id="app" data-slot-header="#header"></div>
<div id="header">
<h1>Title here</h1>
</div>
Then the Vue component
<template>
<div>
<slot name="header"></slot>
</div>
</template>
You can use a dynamic <component> and refer to your #header element as a template reference.
For example
new Vue({
data: () => ({
headerComponent: {
template: '#header' // refer to template element by selector
}
}),
}).$mount('#app')
#app:before,#header:before{position:absolute;top:0;right:0;color:rgba(1,1,1,.5);font-size:.8rem}#app{border:1px solid #666;position:relative}#app:before{content:'Vue app'}#header{position:relative;opacity:.5}#header:before{content:'Original header'}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<div id="app">
<p>Dynamic component rendered here 👇</p>
<component :is="headerComponent"></component>
</div>
<div id="header">
<h1>Title here</h1>
</div>
Slots are mainly used with reusable Vue components so that the parent component can render custom stuff inside designated sections of the child. The root component does not have a parent, so it doesn't make sense to use slots for this.
Why can't you just hard-code the div in the template? Or do you need it to be dynamic; will you be swapping out the header contents in some situations? Please provide more information about what your use-case is, otherwise my answer is "just hard-code it".
Take a look at portal-vue. It allows child components to render templates anywhere in the DOM. This might work for your situation.

How to make a 'Container' component in Vue.js

I'm new to Vue and cannot find a way to implement a React-like 'Wrapper' component with Vue.js, for example, a reusable datagrid component using a 3rd-party some-table component and a pagination component. Intuitively, datagrid will provide the data/props/events that both components need and control the communication between them. In React, this could be done as simply as something like
// inside <Datagrid />
<Table {...someProps} />
<Pagination {...otherProps} />
With Vue, It seems like something like below can only pass props down to children components
// inside Datagrid.vue
<some-table v-bind="$props"></some-table>
I'm not sure if slots could be of help. This wrapper component that I've been struggling for takes all the props/events/slots its children need and pass them down to them so that I could utilize all the functionality that it's children(which probably some 3rd-party components) provide. Moreover, it may also take responsibility for something like data exchange between its children. While datagrid could be a slots wrapper, but what if both table and pagination require a same data prop which I think should reside in datagrid. How to pass this data down to the slots?
// Datagrid.vue
<template>
<div>
<slot name="table"></slot>
<slot name="pagination"></slot>
</div>
</template>
<script>
export default {
name: 'Datagrid',
data() {
return {
data: 'How to share it with table and pagination',
}
},
}
</script>
Some solutions that I could figure out:
Render Functions, but I don't think that complicity is needed in this case
Instead of creating a 'Container' component, simply turn to mixins, but does this mean I have to input <pagination :total="total" :other-props="are-same-for-all-datagrids"></pagination> each time I want a datagrid?
Any examples dealing with such situations in Vue? Thanks in advance!
You want to use slots:
Vue.component('wrapper', { template: '#wrapper' })
new Vue({ el: '#app' })
<!-- wrapper template -->
<script type="text/x-template" id="wrapper">
<div class="wrapper" style="background: beige; padding: 5px;">
This is being wrapped:
<slot></slot>
</div>
</script>
<div id="app">
<wrapper>
<div style="background: aliceblue;">I'm being wrapped!</div>
</wrapper>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script>

Calling different components into rows in React

I have a very basic question that I cannot comprehend and need some help. I'm creating a really small React project for my personal website. I have App.js that is calling all the different components such as header, intro and etc:
import React from 'react';
import Header from './Header';
import Intro from './Intro';
export default class App extends React.Component {
render() {
return (
<div className="container">
<div className="row">
<div className="col-xs-6">
<Header />
</div>
</div>
<div className="row">
<div className="col-xs-6">
<Intro />
</div>
</div>
</div>
)
}
}
As you can assume, header is just the top portion of the page and intro (currently) just says some text. This is what it looks like:
The second component is being blocked by the first component. Can someone explain how React works with components in terms of how it's rendered on the web page? Or is this purely a HTML issue in App.js?

Categories