How to pass Array from Parent component to Child component in reactjs - reactjs

I have two components in my project, the First component is App I got this App component when I created a project. And Second Component is ClassRoom. Now in App.js, I have an array, In that array, I have four different names. Now I have to pass those four names for my child component that is ClassRoom. I know how to loop an Array of objects to React. But I don't know how to loop Array and pass that array to child component so help me to achieve this task.
This is App.js
import React from 'react';
import './App.css';
import ClassRoom from './ClassRoom/ClassRoom';
function App() {
const students = ['shiva', 'krishna', 'ram', 'madhav']
return (
<div className="App">
<ClassRoom></ClassRoom>
</div>
);
}
export default App;
This is App.css
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #09d3ac;
}
This is ClassRoom.js
import React, { Component } from 'react'
import './ClassRoom.css'
export default class ClassRoom extends Component {
render() {
return (
<div>
</div>
)
}
}
This is ClassRoom.css
There is no css in ClassRoom.css
My expected output is I need to pass students Array from Parent Component which is App.js to Child Component which is ClassRoom.js.
If not, clear with my doubt, please put a comment.

Just do <ClassRoom students={students}/>
And in ClassRoom componenets access it using this.props.students

In App.js
function App() {
const students = ['shiva', 'krishna', 'ram', 'madhav']
return (
<div className="App">
<ClassRoom studentsArray = { students } />
</div>
);
}
In ClassRoom.js
export default class ClassRoom extends Component {
render() {
return (
<div>
<ul>
{this.props.studentsArray.map( student => `<li> ${student} </li>` )}
</ul>
</div>
)
}
}

If your ClassRoom component is functional component, then use this.
<ClassRoom students={students}/>
function ClassRoom(props) {
render() {
return (
<div>
{props.students}
</div>
)
}
}
export default ClassRoom;
In functional component use props.students and in class component use this.props.students

Related

.map() in reactJs is not returning anything

i'm new to react and im trying to add render a list of items from an external SidebarData.js file (in the same root /components/..)
i'm not sure why my map function is not returning anything.
i get a list of elements thats correct, but the item.title and item.path seem not to render...
I feel there's a problem with the props.
I tried to write just
render(){
<h1>{SubmenuData[1].title}</h1>
}
and it works fine, but when i try to map on the full array, it doesn't seem to render anything. it renders the correct number of elements, but the title and path are not returning...
Here's my two components : Sidebar (Main one)
import React from 'react'
import styled from 'styled-components'
import { SidebarData } from './SidebarData'
import Submenu from './Submenu'
const Nav = styled.div`
background: #f5f5f5;
color: #7d7d7d;
display:flex;
justify-content:flex-start;
height:100%;
width:15%;
`
const Sidebar = () => {
return (
<>
<Nav>
{SidebarData.map((item, index)=>{
return <Submenu item={item} key={item.index} />
})}
</Nav>
</>
)
}
export default Sidebar (Where i think there's a problem)
and Submenu
import React, { Component } from 'react'
import styled from 'styled-components'
import { Link } from "react-router-dom"
const SidebarLink = styled(Link)`
display: flex;
color: #404040;
`
const SidebarLabel = styled.span`
color:#000;
`
const Submenu = (item)=>{
return (
<SidebarLink to={item.path} >
<SidebarLabel>{item.title}</SidebarLabel>
</SidebarLink>
)
}
export default Submenu
Your style of receiving props is mistake i guess. Destructure the props like:
const Submenu = ({item})=>{
return (
<SidebarLink to={item.path} >
<SidebarLabel>{item.title}</SidebarLabel>
</SidebarLink>
)
}
export default Submenu

Styled Components - use styled component as base for another component

I thought this was possible with styled components
Using the first styled Component Block as the bases for another component like
export const BlockOne = styled.Block
import React, { Component } from 'react';
import { render } from 'react-dom';
import './style.css';
import styled from 'styled-components'
export const Block = styled.div`
width: 100px;
height: 100px;
background: red;
`
export const BlockOne = styled.Block`
background: yellow;
`
const App = () => {
return (
<div>
<Block/>
<BlockOne/>
</div>
);
}
render(<App />, document.getElementById('root'));
Is there a way to do this
Yes, like this
export const BlockOne = styled(Block)`
background: yellow;
`
styled-component only has basic components (tags such as div, span, etc.) as attributes. For anything else, you pass it as a prop.
If you pass a custom component to it, make sure that it accepts a className and that it passes it down to a div or something:
const MyComponent = ({className}) => {
return <div className={className}></div> // styled-component will use this classname to apply the style
}
export const MyStyledComponent = styled(MyComponent)`
background: yellow;
`
Else it would have no effect.

React-Beautiful-Dnd Can't Find Draggable Element with Id

I'm trying to replicate the react-beautiful-dnd tutorial step 4: reorder a list. I've copied the code in the tutorial as far as I can see exactly: https://egghead.io/lessons/react-reorder-a-list-with-react-beautiful-dnd
However, when I run react and try to drag the list items, I get errors like: Unable to find draggable element with id: task-1
If I look at the DOM, I can definitely see an element with that id:
I can't figure out what I'm doing wrong. I printed the id to console to check that it's a string, and it is. Thoughts?
INITIAL-DATA.JS
const initialData = {
tasks : {
"task-1" : { id : "task-1", content : "Take out garbage"},
"task-2" : { id : "task-2", content : "Watch show"},
"task-3" : { id : "task-3", content : "Charge phone"},
"task-4" : { id : "task-4", content : "Cook dinner"},
},
columns : {
"column-1" : {
id : "column-1",
title: "To Do",
taskIds : ["task-1", "task-2", "task-3", "task-4"]
}
},
columnOrder : ["column-1"]
};
export default initialData;
INDEX.JS
import React from 'react';
import ReactDOM from 'react-dom';
import initialData from "./initial-data";
import Column from "./column";
import { DragDropContext } from 'react-beautiful-dnd';
class App extends React.Component {
state = initialData;
// Needs to synchronously update our state to reflect the drag-drop result
// The only required DragDrop callback
onDragEnd = result => {
}
render() {
return (
<DragDropContext onDragEnd={this.onDragEnd}>
{
this.state.columnOrder.map( (columnId) => {
const column = this.state.columns[columnId];
const tasks = column.taskIds.map( taskId => this.state.tasks[taskId]);
return <Column key={column.id} column={column} tasks={tasks} />;
})
}
</DragDropContext>
)
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
COLUMN.JS
import React from "react";
import styled from "styled-components";
import Task from "./task";
import { Droppable } from 'react-beautiful-dnd';
const Container = styled.div`
margin: 8px;
border: 1px solid lightgrey;
border-radius: 2px;
`;
const Title = styled.h3`
padding: 8px;
margin: 0px;
`;
const TaskList = styled.div`
padding: 8px;
`;
export default class Column extends React.Component {
render() {
return (
// Note: Droppables expect their child to be a function that returns a react component
<Container>
<Title>{this.props.column.title}</Title>
<Droppable droppableId={this.props.column.id}>
{ provided => (
// The droppableProps in the provided object (a react-beautiful-dnd object) need to get provided to the object
// you want to designate as your droppable
// {provided.placeholder} // Needs to be added as a child of the component you designate as the droppable
// ref is an attribute of -components. Returns the dom node of the component
<TaskList
ref={provided.innerRef}
{...provided.droppableProps}
>
{ this.props.tasks.map( (task, index) => <Task key={task.id} task={task} index={index} /> ) }
{provided.placeholder}
</TaskList>
)}
</Droppable>
</Container>
)
}
}
TASK.JS
import React from "react";
import styled from "styled-components";
import { Draggable } from 'react-beautiful-dnd';
const Container = styled.div`
border: 1px solid lightgrey;
border-radius: 2px;
padding: 8px;
margin-bottom: 8px;
background-color: white; /* so don't see through when dragging */
`;
export default class Task extends React.Component {
render() {
console.log(this.props.task.id)
console.log(typeof this.props.task.id)
return (
// Required draggable props are draggableId and index
// Note: Draggables expect their child to be a function that returns a react component
<Draggable draggableId={this.props.task.id} index={this.props.index}>
{ provided => (
// The draggbleProps in the provided object (a react-beautiful-dnd object) need to get provided to the object
// you want to designate as your draggable
// DragHandleProps needs to get applied to the part of that object that you want to use to drag the whole object
// ref is an attribute of -components. Returns the dom node of the component
<Container
ref={provided.innerRef}
{...provided.draggbleProps}
{...provided.dragHandleProps}
>
{ this.props.task.content }
</Container>
)}
</Draggable>
)
}
}
There is just a typo in your code: in task.js change {...provided.draggbleProps} to {...provided.draggableProps}
As seen above, the issue here was the typo. Per your comment below that answer, you could help avoid this in the future by using Typescript. It would have shown you an error in your editor at the typo, and also given you autocomplete.

React Progressbar not Visible?

I have created a React progress bar with the help of third part library
import React from "react";
import { css } from "#emotion/core";
import ClipLoader from "react-spinners/ClipLoader";
// Can be a string as well. Need to ensure each key-value pair ends with ;
const override = css`
display: block;
margin: 0 auto;
border-color: red;
`;
class AwesomeComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true
};
}
render() {
return (
<div className="sweet-loading">
<ClipLoader
css={override}
size={150}
color={"#123abc"}
loading={this.state.loading}
/>
</div>
);
}
}
export default AwesomeComponent;
and then import in index.js file
import AwesomeComponent from './awesomeComponent.js';
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<App />
<AwesomeComponent />
</BrowserRouter>
</Provider>,
document.getElementById("root")
);
In my application i want to show this progresbar when data loading from nodejs api or any button clicked ..But nothing visible in GUI related to progressbar.
If you are using class based component for react-promise-tracker then you need to use HOC promiseTrackerHoc :
import React from "react";
import { css } from "#emotion/core";
import ClipLoader from "react-spinners/ClipLoader";
import { promiseTrackerHoc } from "react-promise-tracker"; // <--------- HERE
// Can be a string as well. Need to ensure each key-value pair ends with ;
const override = css`
display: block;
margin: 0 auto;
border-color: red;
`;
class AwesomeComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true
};
}
render() {
return (
this.props.promiseInProgress && // <--------- HERE
<div className="sweet-loading">
<ClipLoader
css={override}
size={150}
color={"#123abc"}
loading={this.state.loading}
/>
</div>
);
}
}
export default promiseTrackerHoc(AwesomeComponent); // <--------- HERE
WORKING DEMO :
Note :
You can checkout DOC, as they have explained everything, I
think you can help you to find out whatever the scenario you want to
implement
In this example, you can see how you can change the visibility of your spinner just changed the local state by clicking on button
https://codesandbox.io/s/modern-monad-4tipc?file=/src/AwesomeComponent.js

React.js router different background image

I want to apply background image for specific component.
I used react-router-dom and my code is below.
[App.js]
import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import Login from './components/Login';
import Home from './components/Home';
class App extends Component {
render() {
return (
<Router>
<div>
<Route exact path="/" component={Login} />
<Route path="/home" component={Home} />
</div>
</Router>
);
}
}
export default App;
[Login.js]
import React, { Component } from 'react';
import './Login.css';
class Login extends Component {
render() {
return (
<div>
Login
</div>
);
}
}
export default Login;
[Login.css]
html {
background-color: red;
}
[Home.js]
import React, { Component } from 'react';
import './Home.css';
class Home extends Component {
render() {
return (
<div>
Home
</div>
);
}
}
export default Home;
[Home.css]
html {
background-color: blue;
}
I set the background-color of Login to red and Home to blue.
But not only Login.js but also Home.js's background color is blue.
How can I set the different background color for each components?
Apply styles to class
Assign a class to the outermost div in Login.js
class Login extends Component {
render() {
return (
<div className="login">
Login
</div>
);
}
}
export default Login;
Now apply styles to the classes
.home{
background-color:blue;
}
.login{
background-color:red;
}
If u want to apply background image for full page try this css..
.home {
background: url("image.jpg");
background-size: cover;
background-repeat: no-repeat;
}
Change the css to:
body {
background-color: red !important;
}
The background color property is set to the body tag, not the html tag. The !important will ensure that this style is applied over any other conflicts you may have.
--Edit--
To apply background colors to the individual components, you should add a class to each of the parent div, and style that class directly like so:
Note: Heights have been added to the styles to ensure 100% vertical fill of the browser, as per the OP's request. It is not required otherwise.
Login.js
import React, { Component } from 'react';
import './Login.css';
class Login extends Component {
render() {
return (
<div className="scene_login">
Login
</div>
);
}
}
export default Login;
Login.css
body, html {
height: 100%;
}
.scene_login {
height: 100%;
background-color: red;
}
Home.js
import React, { Component } from 'react';
import './Home.css';
class Home extends Component {
render() {
return (
<div className="scene__home">
Home
</div>
);
}
}
export default Home;
Home.css
body, html {
height: 100%;
}
.scene__home {
height: 100%;
background-color: blue;
}

Resources