Two Components Connected to Each-other - javascript

Two of my React components are connected together. You might be thinking, if they are both separate components then they shouldn't be connected, right. WRONG.
What I want to do is this. I want to create a footer but the footer is apparently linked to another component. I think this is a react bug but I have decided not to go there in case it's just my fault. I want to change the width of the footer to be max width with the screen but it doesn't work, it changes both of the components width.
.footer {
width: 100%;
}
.footer {
background-color: gray;
border: 1px solid gray;
border-radius: 1px;
height: 100px;
width: 10000px; /*Or 100%*/
}
.otherComponent {
/*For some reason it copies the same attributes as the css one above (there in different files by the way*/
width: 10000px; /*Or 100%*/ /*The one that got copied by react.*/
background-color: gray;
border: 1px solid gray;
border-radius: 1px;
height: 100px;
}
<div class="otherComponent">
</div>
<br />
<p>This is to demonstrate the bug/error that is happening with my program. And what it looks like</p>
<div class="footer">
</div>
Edit:
I am editing this question since I have received comments saying that this question is not understandable, which I understand. The problem is that I want one of the components (which is a code-box for a documentation website that I am working on) to be somehow separated from another component (which is the footer). Every time I apply a style to the footer component the code-box component is having the same styles.
Information
Both of the different styles for the components are in separate folders. They are separated away from each-other using "<br />" tags. The components are placed like this in the App.js file.
{/* Middle of the page */}
<HomeInfo />
{/* Bottom of the page */}
<Footer />
If this edit still doesn't make sense commenting on the post would help.

As there is little to go on here I'll describe one case where this could occur.
Given the following two components and root app.
Component A:
CSS:
.root {
width: 100%;
}
.component-a-heading {
color: blue;
}
Component:
import React from 'react';
import './component-a.css';
const ComponentA = () => {
return (
<div className="root">
<h1 className="component-a-heading">
I am component A
</h1>
</div>
)
}
export default ComponentB;
Component B:
CSS:
.root {
width: 50%;
}
.component-b-heading {
color: red;
}
Component:
import React from 'react';
import './component-b.css';
const ComponentB = () => {
return (
<div className="root">
<h1 className="component-b-heading">
I am component B
</h1>
</div>
)
}
export default ComponentA;
App:
import React from 'react';
import ComponentA from './ComponentA';
import ComponentB from './ComponentB';
const App = () => {
return (
<div>
<ComponentA />
<ComponentB />
</div>
);
}
export default App;
The assumed intended result is that:
ComponentA would be 100% width,
ComponentA heading would be blue,
ComponentB would be 50% width,
ComponentB heading would be red.
The reality is that:
ComponentA would be 50% width,
ComponentA heading would be blue,
ComponentB would be 50% width,
ComponentB heading would be red.
This is caused by the fact that even though the CSS unique to each component is imported per component the resulting CSS is global and effects all components that might use the class names defined within (in the example above .root).
Depending on your bundling process you might end up with a single CSS file that
looks something like this:
.root {
width: 100%;
}
.component-a-heading {
color: blue;
}
.root {
width: 50%;
}
.component-b-heading {
color: red;
}
Or you might end up with the styles inserted into the head of your HTML like this:
<style type="text/css">
.root {
width: 100%;
}
.component-a-heading {
color: blue;
}
</style>
<style>
.root {
width: 50%;
}
.component-b-heading {
color: red;
}
</style>
This is a common mistake for people who come from Angular, where imported CSS is scoped to each component, to React.
One way to get around this is to look at the possibility of using CSS Modules which will allow you to locally scope each imported CSS file (this just makes the CSS class names unique in your resulting bundle).
Another option would be to implement a naming policy to ensure that the class names remain unique between components.

Related

How to position a div inside another div in reactJs?

I want to put the children div on end of parent div , but positioning is not working. i'm using reactJs, NextJs and styled-components for this code;
reactjs code:
<a href={links[indexImg]} target="_blank" >
<Carousel
image={images[indexImg]}
>
<DescriptionText>
<p>{descriptions[indexImg]}</p>
</DescriptionText>
</Carousel>
</a>
styled-componentes code:
export const DescriptionText = styled.div`
color: white;
background-color: black;
background-position: 20px;
opacity: 0.5;
`;
export const Carousel = styled.div`
position: relative;
border-radius: 50px;
border: solid;
border-width: 3px;
border-color: #C2C2C2;
margin: 0;
height: 100%;
width: 100%;
justify-content: flex-end;
background-size: cover;
background-position: center;
background-image:url(${props => props.image});
`;
If your .inner division has a position of absolute and your .outer one gets position relative, the .inner division will adjust itself inside the .outer one. For example: if you want the .inner one to stick to the bottom of the .outer one you can do this:
.outer {
position: relative
}
.inner {
postion: absolute;
bottom: 0
}
first of all install bootstrap from terminal using the command
npm install react-bootstrap bootstrap
suppose you are working with components like Leftsidebar.js , Rightsidebar.js and Content.js which you have imported to index.js
to do this you have install bootstrap in your react.js
follow the steps
index.js blow
import React from 'react';
import ReactDom from 'react-dom';
import Leftsidebar from './Leftsidebar';
import Rightsidebar from './Rightsidebar';
import Content from './Content';
ReactDom.render(
// outer most div
<div class='row'>
<div class='col-4'>
<Leftsidebar/>
</div>
<div class='col-4'>
<Content/>
</div>
<div class='col-4'>
<Rightsidebar/>
</div>
</div>
,documment.getelementbyId('root');
);
simple we have used the grid system to divide the screen into 4 different part out of 12 secondly the above code is just typed in the text editor .but my aim was to guide you how to show data in different layout or positions using react js and it work because i myself use row column to arrange data in position and it is the easiest method .

React adding additional className via props does not follow correct order?

I have a custom component in one file, lets say like that:
import styles from './CustomComponent.module.css'
export default CustomComponent = ({className, onClick, text, ...props}) => {
return (
<div className={styles.outer}>
<div className={`${styles.inner} ${className}`}>{text}</div>
</div>
)
}
That component is imported into another file, which has it's own components and css module:
import styles from './ParentComponent.module.css'
import CustomComponent from '../CustomComponent/CustomComponent.component.js'
export default ParentComponent = () => {
return (
<>
This is an example.
<CustomComponent text='Example' className={styles.overrideStyle} />
</>
)
}
What I want to happen is that the overrideStyle can be used to add css parameters and/or override some existing ones of the container style. What happens is that new parameters are added, if were not previously defined in the inner style, but already existing ones are not overwritten.
For example, if the CustomComponent css is something like:
.outer {
width: 100%;
padding-top: 20px;
}
.inner {
height: 100px;
width: 100%;
}
and overrideStyle is something like this:
.overrideStyle {
height: 500px;
padding: 20px;
}
I expected the resulting css properties of the CustomComponent inner div to behave as follows:
.(combined) {
height: 500px;
width: 100%;
padding: 20px;
}
What I get is:
.(combined){
height: 100px;
width: 100%;
padding: 20px;
}
New properties are added, but existing ones are not overwritten.
What rules are there that I don't understand and how can I force the className that is passed through props to supersede the inner one?
There is a typo in your CustomComponent it should be
<div className={${styles.containerStyle} ${className}}>{text}</div>
instead of only <div className={${styles.container} ${className}}>{text}</div>
Change styles.container to styles.containerStyle in CustomComponent
One fix provided by a friend of mine is to mark the properties of overrideStyle with !important:
.overrideStyle {
height: 500px !important;
padding: 20px !important;
}
This does not solve the problem, but it provides a quick and dirty fix for now.

Module not found: Can't resolve '../images/bg-header-desktop.svg' when importing image into React project

I am building a React project and I am having difficulties in importing a background image. I am getting the error above. The image is in an images folder which is in a public folder. This is my structure of the app.
The image is bg-header-desktop.svg. This is how I want it to look like.
The code I have for the component is the following:
import React from "react";
import "./heading.styles.css";
const Heading = () => (
<header>
<div className="top-background">
</div>
</header>
);
export default Heading;
My css looks like this this:
.top-background {
height: 155px;
background-image: url(../images/bg-header-desktop.svg);
background-color: #5da4a4;
margin-bottom: 70px;
}
This is how I would like it look.
Any help would be appreciated.
It should be like this
.top-background {
height: 155px;
background-image: url("/images/bg-header-desktop.svg");
background-color: #5da4a4;
margin-bottom: 70px;
}

Component Not Rendering Properly in React when using CSS hover pseudo selector

My component is a basic NavBar with different items. When Hovering over the item with the dopdiwn-items class, the NavBar should display those items in a block. Instead, only the first item can be seen, with the others being hidden. The same code, when put into plain HTML and CSS on code pen, works as expected. I discovered if I increase the size of the navbar then the items do show as a large block of text. I listed screenshots, and my code below.
CodePen link: http://codepen.io/anon/pen/dvNvmM
Parent Container:
/*Start dependencies*/
import React, { Component, PropTypes } from 'react';
import Picture from '../../components/picture.jsx';
import ShoppingCart from '../../components/shoppingcart.jsx';
import NavBar from '../../components/navbar.jsx';
import { browserHistory } from 'react-router';
import cart from '../../reducers/index.js';
/*Flag set to know if the client recieved and loaded
Will be set to True once the response from the server
Is loaded and parsed*/
var flag = true;
//Start React class
export default class Products extends Component {
constructor(props) {
super(props);
this.state = {clothingData: 0}
}
render(){
/*if the flag variable is false, server is not done yet retriving
data from the DB and parsing it, thus nothing displayed
*/
if (!flag){
return (
<div>
</div>
);
}
//If flag is true (data is ready to be displayed)
else{
//console.log(this.state.clothingData[0].path);
//console.log(this.state.clothingData[0].fileName);
//console.log(this.state.clothingData);
return (
<div>
<NavBar />
<Picture className = "test" src = {this.state.clothingData} onClick = { () => {browserHistory.push('/Product'); }} name = {"joe"} />
</div>
);
}
}
}
JSX:
import React, { Component, PropTypes } from 'react';
export default class NavBar extends Component {
render(){
return(
<ul className="navbar">
<li className="dropdown">
Clothes
<div className="dropdown-items">
Item
Item
Item
Item
</div>
</li>
<li>About</li>
<li>Policies</li>
<li>How To Rent</li>
<li>Contact</li>
</ul>
);
}
}
CSS:
/*Main HTML Stylesheet*/
html{
font-family: sans-serif;
}
/*div{
background:white;
}*/
/********* NavBar Section **********/
.navbar {
overflow: hidden;
background-color:#B597C3;
}
/* links inside the navigation bar */
.navbar li {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: .625em 5em;
text-decoration: none;
font-size: 17px;
}
/* color of links on hover */
.navbar a:hover {
color:#ffffff;
text-decoration: underline;
}
.navbar a.active {
text-decoration:underline;
}
/* Drop Down Items */
.dropdown-btn {
float:left;
font-size: 1.0625em;
color:white;
border: none;
cursor: pointer;
overflow:hidden;
}
.dropdown{
display: inline-block;
}
.dropdown-items{
position:absolute;
display: none;
margin:0;
min-width: 10em;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.dropdown-items a {
color:white;
padding: 12px 50px;
text-decoration: none;
display: block;
}
.dropdown:hover .dropdown-items {
display: block;
position: absolute;
width: 100%;
height: 100%;
}
/********* NavBar Section **********/
When Hovered:
When Hovered w/ increased size:
Okay, so I think you should not use CSS pseudo selectors with React. I've read questions like this one and my conclusion is in React you should handle the onMouseEnter and onMouseLeave events yourself and then keep a component state that indicates whether the dropdown should be shown or not.
That is the React way of usually doing things: hook up event handler functions and use the component state. When the handler functions are called, you change the state.
I don't know whether CSS pseudo selectors will work properly with React. You can take a look at this GitHub issue. My guess is that whatever you are trying to do doesn't work with the CSS selectors because React uses a virtual DOM and not the actual DOM. So the CSS would be changing the DOM directly kind of thing? It would be nice if other more knowledgeable people could comment on that.
For now, I think you should follow the React way of doing things. Here is the code for what you are trying to do:
import React, { Component, PropTypes } from 'react';
export default class NavBar extends Component {
state = {
showDropdown: false
}
renderDropdown() {
return (
<div className="dropdown-items">
Item
Item
Item
Item
</div>
);
}
render() {
return (
<ul className="navbar">
<li
className="dropdown"
onMouseEnter={() => this.setState({ showDropdown: true })}
onMouseLeave={() => this.setState({ showDropdown: false })}
>
Clothes
{this.state.showDropdown ? this.renderDropdown() : null}
</li>
<li>About</li>
<li>Policies</li>
<li>How To Rent</li>
<li>Contact</li>
</ul>
);
}
}
Keep in mind you should remove the CSS rule for the hover pseudo selector for the items div, as well as the display: none for the dropdown. After doing that, everything should be OK.
Note: I used a property initializer to set up the initial state for the component. Babel should take care of transpiling that. In case that doesn't work, set the initial state in the constructor.

Stacked divs resizing each other

This is probably going to be a long one:
I'm trying to make a chat application (similar to Slack) with Electron, React and Socket.io. My issue is mostly dealing with React and CSS/Sass though. Right now I've got a few bootstrap, but I'm not really using the grid system at all, so that can/may be scrapped.
The structure of the page is as follows: I've got a footer with a resizable textarea. above it I've got a div that will be holding messages. That div has overflow-y set to scroll, that way the scrollbar is only for the messages and doesn't take the entire page's space. I want the div to get shorter as the footer grows with the textarea. Right now though the div just extends under the footer (and the scrollbar along with it). Since the messages fill the div there's nothing to scroll and no thumb (I think that's the correct term) in the scrollbar.
React component (I've only included one li for the sake of brevity, but in my code I've got bunch):
import React from 'react';
import { Button, Image, Media, Panel } from 'react-bootstrap';
export default class Page extends React.Component {
constructor(props) {
super(props);
this.state = props;
}
footerResize() {
// code to resize messages div, or at least get some information about
// the footer's height
}
render() {
return (
<div className="page">
<div className="sidebar">
</div>
<div className="container-fluid">
<div classname="messages">
<ul>
<li className="message>
<Media>
<Media.Left>
<Image src="#" />
</Media.Left>
<Media.Body>
<Media.Heading>
Name
</Media.Heading>
Message content
</Media.Body>
</Media>
<li>
</ul>
</div>
<footer>
<textarea defaultValue="test text" />
</footer>
</div>
</div>
);
}
}
_page.scss (most of this is from the file name _page.scss but a few properties are pulled in from other files here so I'm only typing one file's contents):
$dark-grey: #383838;
$default-font-color: #FFFFFF;
$light-grey: #474747;
$light-light-grey: #908E8F
$sidebar-width: 250px;
body {
color: $default-font-color;
overflow: hidden;
}
ul {
list-style: none;
}
.page {
background-color: $light-grey;
height: 100vh;
.sidebar {
background-color: $light-light-grey;
position: fixed;
height: 100%;
width: $sidebar-width;
.container-fluid {
margin-left: $sidebar-width;
padding-left: 0px;
padding-right: 0px;
.messages {
overflow-y: scroll;
}
footer {
background-color: $main-green;
bottom: 0;
padding-bottom: 10px;
padding-left: 10px;
padding-right: 10px;
padding-top: 10px;
position: fixed;
width: calc(100% - #{$sidebar-width});
}
}
}
}
I've tried a bunch of different things to get this to work. I've tried a few node modules. I've tried adding event listeners both by adding ref='footer' to the footer and referring to it as this.refs.footer in when adding the event listener and by giving footer and id and using document.getElementById('footer'). The whatever I try I can't get any information about the footer's size in the footerResize. Any help on this would be appreciated. I don't even know if this is something I should be doing with sass properties or whether I need js/React to do this.
You can try out a flexbox based layout.
This for .container-fluid
display: flex;
flex-direction: column;
This for .messages
flex: 1;
Then you remove position: fixed from footer
What this does: it sets the height of .messages to fill its parent's remaining space. So when footer gets bigger, there is less remaining space and .messages will shrink.
Please note that you will need to add vendor prefixes for flexbox depending on your targeted browser support.

Categories

Resources