passing component & props in function react js - reactjs

i have 2 components & i want to pass data by input from parent component to the child component, i got stuck to pass the data to the child component and display or render the child component
is there any technique to pass the props to the child components & render it?
and when i see the console on developer tools there is nothing wrong/happen except the console.log code
import React, {Component} from 'react';
import ReactDOM from'react-dom';
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
//props.keyword
const keyword = 'avenger';
const API = `https://api.themoviedb.org/3/search/movie?api_key=341c549444f65b6a022eea5fc24f5b77&language=en-US&query=${keyword}&page=1&include_adult=false`;
const DEFAULT_QUERY = 'redux';
class MovieSearch extends Component{
constructor(props){
super(props);
this.state={
movies:[]
}
}
componentDidMount(){
fetch(API + DEFAULT_QUERY)
.then(response=>response.json())
.then(data=>{
this.setState({movies:data.results})
})
}
render(){
const {movies} = this.state;
return(
<div className="row container">
{movies.map(movie =>
<div className="col-md-4">
<div className="card" style={{width: '15rem'}} key={movie.id}>
<img src="" className="card-img-top" alt="..."/>
<div className="card-body">
<h5 className="card-title">{movie.title}</h5>
<p>{movie.id}</p>
<Link to="/movie/detail">Detail</Link>
</div>
</div>
</div>
)}
</div>
)
}
}
export default MovieSearch;
import React, { Component } from"react";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
//component
import Jumbotron from "./jumbotron";
import MovieList from "./movieList";
import MovieSearch from"./MovieSearch";
import Movie from"./Movie";
//HOC
const idMovie = (WrappedComponent)=>{
class IdMovie extends Component{
constructor(props){
super(props)
this.state={}
}
}
}
//route start here
class Main extends Component{
constructor(props){
super(props)
this.state={
keyword: ''
}
this.handleInput = this.handleInput.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleInput(event){
this.setState({keyword:event.target.value})
}
handleSubmit(event){
console.log(this.state.keyword)
event.preventDefault()
}
render(){
return (
<Router>
<nav className="navbar navbar-expand-lg navbar-dark bg-dark">
<Link className="navbar-brand" to="/">Carifilm</Link>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav mr-auto">
<li className="nav-item active">
<Link className="nav-link" to="/">Home <span className="sr-only">(current)</span></Link>
</li>
<li className="nav-item">
<Link className="nav-link" to="/movies">Movies</Link>
</li>
<li className="nav-item">
<Link className="nav-link" to="/search-movie">Cari film</Link>
</li>
</ul>
<form className="form-inline my-2 my-lg-0" onSubmit={this.handleSubmit}>
<input className="form-control mr-sm-2"
type="search" placeholder="Search"
aria-label="Search"
value={this.state.keyword}
onChange={this.handleInput}/>
<button className="btn btn-outline-success my-2 my-sm-0" type="submit" value="submit">Search</button>
</form>
</div>
</nav>
<Switch>
<Route exact path="/">
<Home/>
</Route>
<Route path="/movies">
<Movies/>
</Route>
<Route path="/movie/detail">
<MovieDetail/>
</Route>
<Route path="/search-movie">
<CariFilm/>
</Route>
</Switch>
</Router>
)}
}
export default Main;
function Home(){
return(
<Jumbotron/>
)
}
function Movies(){
return(
<MovieList/>
)
}
function MovieDetail(){
return(
<Movie/>
)
}
function CariFilm(props){
return(
<MovieSearch/>
)
}

Please check this example. Here I passed items into my Child Component and displayed items in child component.
Parent
import React, {Component, useEffect, useState} from 'react';
import {PChild} from "./PChild";
export class Parent extends Component {
constructor(props) {
super(props);
this.state = {items: []};
}
componentDidMount() {
let json = [];
json.push({track: { id:1, name: 'Black Sabbath, from the album Black Sabbath (1970)'}});
json.push({track: { id:2, name: 'Blackfield, from the album Blackfield (2004)'}});
json.push({track: { id:3, name: 'Bo Diddley, from the album Bo Diddley (1958)'}});
json.push({track: { id:4, name: 'Damn Yankees, from the album Damn Yankees (1990)'}});
this.setState({items: json});
}
render() {
return (
<div>
<PChild items={this.state.items} name="Khabir"/>
</div>
);
}
}
Child
import React, {useEffect, useState} from 'react';
// Parent to Child communication
export class PChild extends React.Component {
componentDidUpdate() {
console.log(this.props.items);
console.log(this.props.name);
}
render() {
return (
<div>
{this.props.items.map((item, i) => {
return <li key={item.track.id}>
{(`Item ${i+1} - ${item.track.name}`)}
</li>
})}
</div>
);
}
}

Related

Redirect to another component after submit in react

I am new to React. I would like to redirect to another page (another component) called MainModule from the login form after clicking the submit button.
This is my Login Form=>
import React, {Component} from "react";
import { withRouter} from 'react-router-dom';
import {Button,FormGroup,FormControl,FormLabel,Form} from "react-bootstrap";
class Login extends Component {
constructor(props){
super(props);
this.state={
email:"",
password:""
};
}
handelChange = event =>{
this.setState({
[event.target.id]:event.target.value
},()=>{
});
}
handelSubmit = event => {
event.preventDefault();
this.props.history.push('/MainModule');
}
render()
{
return (
<div className="Login">
<Form onSubmit={this.handelSubmit}>
<FormGroup controlId="email">
<FormLabel>Email</FormLabel>
<FormControl autoFocus type="email" value={this.state.email} onChange={this.handelChange}/>
</FormGroup>
<FormGroup controlId="password">
<FormLabel>Password</FormLabel>
<FormControl type="password" value={this.state.password} onChange={this.handelChange}/>
</FormGroup>
<Button type="submit">Login</Button>
</Form>
</div>
)
}
}
export default withRouter(Login);
but the problem is after I clicking the submit button, url change to MainModule but MainMoudle form is not shown and just showing the current login form.I think this needs to defind the route for MainModule and I don't know how to do that. Please help.
Update
My MainModules =>
import React from 'react';
import { Route, Link,Switch,BrowserRouter } from "react-router-dom";
import allowance from './components/master/allowance';
class MainModule extends React.Component {
// constructor(props){
// super(props)
// }
render(){
return(
<div className="mainform">
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<Link className="navbar-brand" to="/MainModule">TMS</Link>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarNavAltMarkup">
<div className="navbar-nav">
<Link className="nav-item nav-link" to={'/allowance'}>Allowance</Link>
</div>
</div>
</nav>
<div id="maincontent">
<Route path='/allowance' component={allowance} />
</div>
</div>
)
}
}
export default MainModule;
You are correct, you do have to define a route for your MainModule component.
In your App.js file, which is where I'm assuming you have set up your Routes:
import React from "react"
import { BrowserRouter, Route } from "react-router-dom"
import Login from "/yourcomponentfolder/Login"
import MainModule from "/yourcomponentfolder/MainModule"
const App = () => {
return(
<BrowserRouter>
<div>
//Using exact tells react-router that you will only render this component if the URL matches exactly with the path definition.
<Route path="/" component={Login} exact/>
<Route path="/MainModule" component={MainModule}/>
</div>
</BrowserRouter>
)
}
It's pretty cut and dry, you use the Route component, give it a path, and a component to render.

Calling function in App.js from another component

I'm new to ReactJS and want to use this library: https://github.com/teodosii/react-notifications-component
It states that "You must place ReactNotificationsComponent component at the root level of the application in order to work properly, otherwise it might conflict with other DOM elements due to the positioning."
I followed the usage guide, but I'm not sure how to call the addNotification function from a child component.
App.js
import React, { Component } from 'react'
import ReactNotification from "react-notifications-component"
import Header from './components/Header'
class App extends Component {
constructor() {
super()
this.addNotification = this.addNotification.bind(this)
this.notificationDOMRef = React.createRef()
}
addNotification() {
this.notificationDOMRef.current.addNotification({
title: "Awesomeness",
message: "Awesome Notifications!",
type: "success",
insert: "top",
container: "top-right",
animationIn: ["animated", "fadeIn"],
animationOut: ["animated", "fadeOut"],
dismiss: { duration: 5000 },
dismissable: { click: true }
})
}
render() {
return (
<div>
<ReactNotification ref={this.notificationDOMRef} />
<Header />
</div>
)
}
}
export default App
Header.js
import React, { Component } from 'react'
import logo from "../assets/images/logo/logo-light.png"
import { BrowserRouter as Router, Route, NavLink, Switch } from "react-router-dom"
import Home from '../pages/Home'
import Apply from '../pages/Apply'
export default class Header extends Component {
render() {
return (
<Router>
<div>
<Route render={({ location }) => (
<header id="navbar-spy" className="header header-1 header-dark header-fixed">
<nav id="primary-menu" className="navbar navbar-fixed-top">
<div className="container">
<div className="navbar-header">
<button type="button" className="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse-1" aria-expanded="false">
<span className="sr-only">Toggle navigation</span>
<span className="icon-bar"></span>
<span className="icon-bar"></span>
<span className="icon-bar"></span>
</button>
<img className="logo-light" src={logo} alt="Logo" draggable="false" />
</div>
<div className="collapse navbar-collapse pull-right" id="navbar-collapse-1">
<ul className="nav navbar-nav nav-pos-right navbar-left">
<li className="">
<NavLink to="/" className="menu-item">Home</NavLink>
</li>
<li className="">
<NavLink to="/apply" className="menu-item">Apply</NavLink>
</li>
</ul>
</div>
</div>
</nav>
</header>
)}
/>
<Route path="/" exact component={Home} />
<Route path="/apply" exact component={Apply} />
</div>
</Router>
)
}
}
When you click the "Apply" link, it loads the Apply component. In that component, they can receive an error/success notification. From that component is where I want to be able to tell the ReactNotification in App.js what title, message, and type to render. How can I communicate from Apply.js to App.js?
You can pass the addNotification function to your Header component:
<Header addNotification={this.addNotification} />
And you can continue to pass it down to other child components, until you are ready to call it.

React js communication between parent and child component using props send data from shop to prod details component

This is a shop Component which is the parent component in which I have an image on click handler in which I need to send data to a child component called Prod Details.
And the click event is detailMovie so need to pass it to child using props
The child component should should display the selected data from the function
import React from "react";
import { Link, browserHistory } from "react-router";
import { ProdDetails } from "./ProductDetails";
// import ProductsJSON from "../data/products.json";
export class Shop extends React.Component {
// to route to details page from list
onNavigateProdDetails() {
browserHistory.push("/proddetails");
}
constructor(props) {
super(props);
this.state = {
data: [],
selectedData: {}
};
}
//API Call to fetch data
componentDidMount() {
fetch("https://facebook.github.io/react-native/movies.json")
.then(Response => Response.json())
.then(findresponse => {
console.log(findresponse.movies);
this.setState({
data: findresponse.movies
});
});
}
detailMovie(moviedata) {
//this.props.clickedItem = moviedata;
this.selectedMovieList = moviedata;
};
render() {
// find the clicked item and local storage
let selectedMovie;
return (
<div className="shop pad-30">
<h1>Latest Arrivals</h1>
<div className="shop-inner">
<div className="prods-wrap">
{this.state.data.map((moviedata, i) => {
return (
<div
key={moviedata.id}
onClick={() => this.detailMovie(moviedata)}
data-key={moviedata.id}
className="shop-inner-each"
>
<Link to="/proddetails">
<div className="shop-inner-each-img">
<img src={moviedata.image} className="img-fluid" />
</div>
</Link>
<div className="shop-inner-each-details">
<div className="shop-inner-each-details-left">
<Link to="/proddetails">
<h3>{moviedata.title}</h3>
</Link>
<p>$ {moviedata.releaseYear}</p>
</div>
<div className="shop-inner-each-details-right">
<button type="button" className="fi flaticon-like" />
<button
type="button"
className="fi flaticon-shopping-cart"
/>
</div>
</div>
</div>
);
})}
</div>
</div>
</div>
);
}
}
import React from "react";
import { browserHistory, Link } from "react-router";
export class ProdDetails extends React.Component {
onNavigateShop() {
browserHistory.push("/shop");
}
constructor(props) {
super(props);
// copy current list of items
}
render() {
return (
<div className="proddetails">
<div className="proddetails-left">
<img src="" />
</div>
<div className="proddetails-right">
<div className="proddetails-right-inner">
<Link to="/shop" className="btn btn-pagination">
<i className="fi flaticon-left-arrow" /> Back
</Link>
{/* <h2>{this.props.movieData.title}</h2>
<h3>$ {this.props.movieData.releaseYear}</h3> */}
{/* <p>{this.updatedItem.description}</p> */}
<div className="actions">
<button type="button" className="btn btn-prime">
<i className="fi flaticon-like" /> Add to Wishlist
</button>
<button type="button" className="btn btn-prime">
<i className="fi flaticon-shopping-cart" /> Add to Cart
</button>
</div>
</div>
</div>
</div>
);
}
}

Understanding React browser history

I am building a web app using react 16 and react-router v4. My app has index.js like this -
import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
import Bootstrap from "bootstrap/dist/css/bootstrap.css";
import 'font-awesome/css/font-awesome.min.css';
import "../assets/css/clean-blog.css";
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter> ,
document.getElementById('app')
);
My App.js looks like this -
"use strict";
import React from "react";
import Header from "./layout/header";
import Body from "./layout/body";
import Footer from "./layout/footer";
class App extends React.Component {
render() {
return (
<div>
<Header />
<Body />
<Footer />
</div>
);
}
};
export default App;
In my Header component, I have a search box and I want that when user clicks on seacrh submit button, then they should be redirected to /seacrh url. I managed to get that. Please look at handleSubmit function
"use strict";
import React from "react";
import { Link } from 'react-router-dom';
import Notifications, {notify} from 'react-notify-toast';
import { withRouter } from 'react-router-dom';
class Header extends React.Component {
constructor(props) {
super(props);
this.state = {
searchTerm:''
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({searchTerm: event.target.value});
}
handleSubmit(event) {
event.preventDefault();
//console.log(this.props);
//console.log(this.state.searchTerm);
this.props.history.replace({
pathname:'/search',
searchTerm:this.state.searchTerm
});
}
render() {
return (
<nav className="navbar navbar-expand-lg navbar-light fixed-top" id="mainNav">
<div className="container">
<Link to='/'>My Library</Link>
<button className="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
Menu
<i className="fa fa-bars"></i>
</button>
<div className="collapse navbar-collapse" id="navbarResponsive">
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<Link to='/'>Home</Link>
</li>
<li className="nav-item">
<Link to='/authors'>Authors</Link>
</li>
<li className="nav-item">
<Link to='/books'>Books</Link>
</li>
</ul>
<form className="form-inline my-2 my-lg-0" onSubmit={this.handleSubmit} type="post">
<input className="form-control mr-sm-2" type="text" placeholder="Search" onChange={this.handleChange} name="searchTerm"/>
<button className="btn btn-outline-secondary btn-md " type="submit">Search</button>
</form>
</div>
</div>
</nav>
);
}
};
export default withRouter(Header);
This works fine when for all urls except when I try to submit from /search url then nothing happens. What I mean is that handleSubmit function gets called but then it does not fire the redirect call.
I am very new to react and would like to have some insight on how best should I handle this.

React - how to pass state to another component

I'm trying to figure out how to notify another component about a state change. Let's say I have 3 components - App.jsx,Header.jsx,and SidebarPush.jsx and all I'm simply trying to do is toggle a class with an onClick.
So the Header.jsx file will have 2 buttons when clicked will toggle the states to true or false. The other 2 components App.jsx and Header.jsx will need to know about these state changes so they can toggle a class
whenever those states change.
App.jsx
import React from 'react';
import Header from 'Header';
import classNames from "classnames";
import SidebarPush from 'SidebarPush';
import PageWrapper from 'PageWrapper';
var MainWrapper = React.createClass({
render: function() {
return (
<div className={classNames({ 'wrapper': false, 'SidebarPush-collapsed': !this.state.sidbarPushCollapsed })}>
<Header/>
<SidebarPush/>
<PageWrapper>
{this.props.children}
</PageWrapper>
</div>
);
}
});
module.exports = MainWrapper;
Header.jsx
import React from 'react';
import ReactDom from 'react-dom';
class Header extends React.Component {
constructor() {
super();
this.state = {
sidbarPushCollapsed: false,
profileCollapsed: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({
sidbarPushCollapsed: !this.state.sidbarPushCollapsed,
profileCollapsed: !this.state.profileCollapsed
});
}
render() {
return (
<header id="header">
<ul>
<li>
<button type="button" id="sidbarPush" onClick={this.handleClick} profile={this.state.profileCollapsed}>
<i className="fa fa-bars"></i>
</button>
</li>
<li>
<button type="button" id="profile" onClick={this.handleClick}>
<i className="icon-user"></i>
</button>
</li>
</ul>
<ul>
<li>
<button id="sidbarOverlay" onClick={this.handleClick}>
<i className="fa fa-indent"></i>
</button>
</li>
</ul>
</header>
);
}
};
module.exports = Header;
SidebarPush.jsx
import React from 'react';
import ReactDom from 'react-dom';
import classNames from "classnames";
class SidebarPush extends React.Component {
render() {
return (
<aside className="sidebarPush">
<div className={classNames({ 'sidebar-profile': true, 'hidden': !this.state.pagesCollapsed })}>
....
</div>
<nav className="sidebarNav">
....
</nav>
</aside>
);
}
}
export default SidebarPush;
Move all of your state and your handleClick function from Header to your MainWrapper component.
Then pass values as props to all components that need to share this functionality.
class MainWrapper extends React.Component {
constructor() {
super();
this.state = {
sidbarPushCollapsed: false,
profileCollapsed: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({
sidbarPushCollapsed: !this.state.sidbarPushCollapsed,
profileCollapsed: !this.state.profileCollapsed
});
}
render() {
return (
//...
<Header
handleClick={this.handleClick}
sidbarPushCollapsed={this.state.sidbarPushCollapsed}
profileCollapsed={this.state.profileCollapsed} />
);
Then in your Header's render() method, you'd use this.props:
<button type="button" id="sidbarPush" onClick={this.props.handleClick} profile={this.props.profileCollapsed}>

Resources