I have an array in the parent component, and I want to pass this state value to another componenet which will the props for another component.
import React, { Component } from "react";
import Bookings from "./components/Bookings";
import Meals from "./components/Meals";
import Error from "./components/Error";
class App extends Component {
state = {
values: [{ name: "John Doe", date: "2017-09-15" }]
};
handleGuestInfo = () => {
console.log("Here");
//console.log(this.state.name, "here");
};
render() {
return (
<div className="container-fluid">
<center>
<h2>Hacker Hostel</h2>
</center>
<div className="container">
<Bookings onGuestChange={this.handleGuestInfo} />
<Error />
<Meals name={this.state.values} date={this.state.values} />
</div>
</div>
);
}
}
export default App;
import React, { Component } from "react";
class Meals extends Component {
render() {
return (
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<ol id="list">
<div>
<li className="morning">
Breakfast for {this.props.name} on {this.props.date}
</li>
<li className="afternoon">Lunch for insert_hacker_name</li>
<li className="night">Dinner for insert_hacker_name</li>
</div>
</ol>
</div>
);
}
}
export default Meals;
Any help will be appreciated, I want to get name and date to the meals.js file from app.js, I am able to pass value for function.
You can map over values state and render the Meal component according to that.
class App extends React.Component {
state = {
values: [{ name: "John Doe", date: "2017-09-15" }]
};
handleGuestInfo = () => {
console.log("Here");
//console.log(this.state.name, "here");
};
render() {
return (
<div className="container-fluid">
<center>
<h2>Hacker Hostel</h2>
</center>
<div className="container">
{this.state.values.map(value =>(
<Meals key={value.name} name={value.name} date={value.date} />
))}
</div>
</div>
);
}
}
class Meals extends React.Component {
render() {
return (
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<ol id="list">
<div>
{this.props.valuy}
<li className="morning">
Breakfast for {this.props.name} on {this.props.date}
</li>
<li className="afternoon">Lunch for insert_hacker_name</li>
<li className="night">Dinner for insert_hacker_name</li>
</div>
</ol>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root" />
Related
I'm new in ReactJs and I only know a few things as of now. I'm trying to create this Google map with directions which is successful
MapRender.js
import React from 'react';
import { render } from 'react-dom';
import Map from './mapProps';
//import './style.css';
const googleMapsApiKey = "API_KEY";
export default function FinalMap() {
const FinalMap = props => {
const {places} = props;
const {
loadingElement,
containerElement,
mapElement,
defaultCenter,
defaultZoom
} = props;
return (
<Map
googleMapURL={
'https://maps.googleapis.com/maps/api/js?key=' +
googleMapsApiKey +
'&libraries=geometry,drawing,places'
}
markers={places}
loadingElement={loadingElement || <div style={{height: `100%`}}/>}
containerElement={containerElement || <div style={{height: "80vh"}}/>}
mapElement={mapElement || <div style={{height: `100%`}}/>}
defaultCenter={defaultCenter || {lat: 25.798939, lng: -80.291409}}
defaultZoom={defaultZoom || 13}
/>
);
};
const places = [
{latitude:14.7539407,longitude:121.0338431},
{latitude: 14.625981794368357,longitude: 121.06170033978614},
]
render(<FinalMap defaultZoom={12} places={places} />, document.getElementById('root'));
}
And this is my App.js
import React from 'react';
import picture1 from '../../src/picture1.jpg';
import RechartBar from '../postlist/Rechart-Bar';
import RechartLine from '../postlist/Rechart-Line';
import driverstat from '../driverprofiles/driverstat';
import AppMap from './Maps/map';
import MapRender from './Maps/MapRender';
function Home() {
return (
<div className="Bodydiv">
<div className="homediv">
<div className="userdiv">
<div className="userdiv-profile">
<div className="userdiv-profile-photo">
<img src={picture1} className="photo" alt="picture1"></img>
</div>
<div className="userdiv-profile-name">
</div>
<div className="userdiv-profile-name">
Name:
</div>
<div className="userdiv-profile-name">
Driver ID:
</div>
<div className="userdiv-profile-name">
Plate Number:
</div>
<div className="userdiv-profile-name">
Status:
</div>
</div>
<div className="userdiv-stats">
Statistics
{driverstat.map((item, index) => {
return (
<li key={index} className={item.cName}>
{item.icon}
</li>
);
})}
<h4 class="view-history">View History</h4>
<input type="button" className="backtodrivers-btn" alt="back" value="Back"/>
</div>
</div>
<div className='mapdiv'>
<MapRender/>
</div>
</div>
<RechartBar/>
<RechartLine/>
</div>
);
}
export default Home;
The problem is It does run but it made my other elements go away because the map was rendered as seen in the last part of my MapRender.js, what I wanted to do is place this in a component and then call that component in my App.js (Similar to what I have done in RechartBar and RechartLine at the end of my App.js.
Thanks
You are replacing entire app with FinalMap component using this line.
Remove this line from MapRenderer.js
render(<FinalMap defaultZoom={12} places={places} />, document.getElementById('root'));
import React from 'react';
import { render } from 'react-dom';
import Map from './mapProps';
//import './style.css';
const googleMapsApiKey = "API_KEY";
export default function FinalMap(props) {
const {
places,
loadingElement,
containerElement,
mapElement,
defaultCenter,
defaultZoom
} = props;
return (
<Map
googleMapURL={
'https://maps.googleapis.com/maps/api/js?key=' +
googleMapsApiKey +
'&libraries=geometry,drawing,places'
}
markers={places}
loadingElement={loadingElement || <div style={{height: `100%`}}/>}
containerElement={containerElement || <div style={{height: "80vh"}}/>}
mapElement={mapElement || <div style={{height: `100%`}}/>}
defaultCenter={defaultCenter || {lat: 25.798939, lng: -80.291409}}
defaultZoom={defaultZoom || 13}
/>
);
};
Then in App.js
import React from 'react';
import picture1 from '../../src/picture1.jpg';
import RechartBar from '../postlist/Rechart-Bar';
import RechartLine from '../postlist/Rechart-Line';
import driverstat from '../driverprofiles/driverstat';
import AppMap from './Maps/map';
import MapRender from './Maps/MapRender';
function Home() {
return (
<div className="Bodydiv">
<div className="homediv">
<div className="userdiv">
<div className="userdiv-profile">
<div className="userdiv-profile-photo">
<img src={picture1} className="photo" alt="picture1"></img>
</div>
<div className="userdiv-profile-name">
</div>
<div className="userdiv-profile-name">
Name:
</div>
<div className="userdiv-profile-name">
Driver ID:
</div>
<div className="userdiv-profile-name">
Plate Number:
</div>
<div className="userdiv-profile-name">
Status:
</div>
</div>
<div className="userdiv-stats">
Statistics
{driverstat.map((item, index) => {
return (
<li key={index} className={item.cName}>
{item.icon}
</li>
);
})}
<h4 class="view-history">View History</h4>
<input type="button" className="backtodrivers-btn" alt="back" value="Back"/>
</div>
</div>
<div className='mapdiv'>
<MapRender places={[
{latitude:14.7539407,longitude:121.0338431},
{latitude: 14.625981794368357,longitude: 121.06170033978614},
]}/>
</div>
</div>
<RechartBar/>
<RechartLine/>
</div>
);
}
export default Home;
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>
);
}
}
I'm building a simple web app using React where the user enters a valid username to bring up a diary of recently eaten food items. I have a single username field at the top of the page that I want to be sticky as the user scrolls down the entirety of the page. But as it is now, the username field is just scrolling out of view like a normal component. What am I missing? Any help would be appreciated.
app.js
import React, { Component } from 'react';
import {StickyContainer, Sticky} from 'react-sticky';
import Username from '../containers/username';
import DiaryList from '../containers/diary_list';
export default class App extends Component {
render() {
return (
<div>
<h1 className="text-xs-center">Diary</h1>
<StickyContainer>
<Sticky>
{() => {
return <Username />}}
</Sticky>
<DiaryList />
</StickyContainer>
</div>
);
}
}
username.js
import React, {Component} from 'react';
import {connect} from 'react-redux';
import {fetchUser} from '../actions/index';
class Username extends Component {
constructor(props){
super(props);
this.state = {term: ''};
this.onInputChange = this.onInputChange.bind(this);
}
onInputChange(event) {
this.setState({term: event.target.value},
() => this.props.fetchUser(this.state.term)
);
}
render(){
return(
<div className="username">
<span className="username-field">Username:</span>
<input value = {this.state.term}
onChange={this.onInputChange} />
</div>
)
}
}
export default connect(null, {fetchUser})(Username);
diary_list.js
import React, {Component} from 'react';
import {connect} from 'react-redux';
import DishChart from './dish_chart';
class DiaryList extends Component {
constructor(props) {
super(props);
this.state = {width: $(window).width(),
height: $(window).height()
}
this.updateDimensions = this.updateDimensions.bind(this);
}
componentDidMount() {
window.addEventListener("resize", this.updateDimensions);
}
componentWillUnmount() {
window.removeEventListener("resize", this.updateDimensions);
}
updateDimensions() {
this.setState({width: $(window).width(), height: $(window).height()});
}
renderDiary(diaryData, key=diaryData.dishId) {
return (
<div key={diaryData.dishId}>
<div className="col-sm-6 col-md-4 col-lg-3" >
<ul className="list-group">
<li className="list-group-item">
<img className="img-thumbnail"src={diaryData.imageLink} alt="No image available."/>
</li>
<li className="list-group-item">{diaryData.dishName}</li>
<li className="list-group-item">Price: {diaryData.price}</li>
<li className="list-group-item">Calories: {diaryData.calories}</li>
<li className="list-group-item">Health Score: {diaryData.healthScoreM}</li>
<div className="container-fluid">
<li className="list-group-item row">
<div className="col-xs-4 carbs">
{`${diaryData.carbohydrates}G Carbs`}
</div>
<div className="col-xs-4 fat">
{`${diaryData.totalFat}G Fat`}
</div>
<div className="col-xs-4 protein">
{`${diaryData.protein}G Protein`}
</div>
</li>
</div>
<li className="list-group-item recharts-wrapper">
<DishChart data={diaryData} />
</li>
</ul>
</div>
{($(window).width() >= 480 && $(window).width() < 768) &&
key % 2 == 1 &&
<div className="clearfix visible-sm-block"></div>
}
{($(window).width() >= 768 && $(window).width() < 992) &&
key % 3 == 2 &&
<div className="clearfix visible-md-block"></div>
}
{$(window).width() >= 992 &&
key % 4 == 3 &&
<div className="clearfix visible-lg-block"></div>
}
</div>
)
}
render() {
if (this.props.diary.data == undefined) {
return (
<div>
Please enter a valid username.
</div>
)
}
return (
<div className="diary">
{this.props.diary.data.map(this.renderDiary)}
</div>
);
}
}
function mapStateToProps(state) {
return {
diary: state.diary
};
}
export default connect(mapStateToProps)(DiaryList);
Im trying to create a ReactList that contains the activities on state, but i can't manage to reference the variable state from inside renderItemOtherActi when called as
itemRenderer={this.renderItemOtherActi}
I tryed using
itemRenderer={::this.renderItemOtherActi}
or
itemRenderer={this.renderItemOtherActi.bind(this)}
but nothing worked, I'm sure it's a really dumb mistake, sorry in advance im new in JSX. Thanks a lot!
import React from 'react';
import ReactList from 'react-list';
import './css/bootstrap.min.css';
import './css/small-business.css';
import Navbar from './Navbar';
import Footer from './Footer';
class Activity_Page extends React.Component {
state = {
my_activities: [
{
name:"Yoga"
},
{
name:"Crossfit"
}],
other_activities: [
{
name:"Zamba"
},
{
name:"Spinnig"
}]
};
return_state(){
return this.state;
}
renderItemMyActi(index, key) {
return <div key={key}>Yoga</div>;
}
renderItemOtherActi(index, key) {
return <div key={key}>{this.state.my_activities[index].name}</div>;
}
render() {
return (
<div>
<Navbar />
<div className="Activity_Page container">
<div className="row">
<div className="col-lg-10">
<h3>Actividades a las que estoy inscripto</h3>
<div style={{overflow: 'auto', maxHeight: 400}}>
<ReactList
itemRenderer={this.renderItemMyActi}
length={this.state.my_activities.length}
type='uniform'
/>
</div>
<h3>Actividades a las que no estoy inscripto</h3>
<div style={{overflow: 'auto', maxHeight: 400}}>
<ReactList
itemRenderer={this.renderItemOtherActi}
length={this.state.other_activities.length}
type='uniform'
/>
</div>
</div>
</div>
<footer className="Footer">
<div className="row">
<div className="col-lg-12">
<Footer />
</div>
</div>
</footer>
</div>
</div>
);
}
}
export default Activity_Page;
you either
bind it in the constructor:
constructor(props){
super(props);
this.renderItemOtherActi=this.renderItemOtherActi.bind(this);
}
or use arrow function
renderItemOtherActi = (index, key) => {
// ...
}
I have started to learn react + redux recently. Prior to that I have not had experience with this sort of stack.
So I ran into a problem where I do not understand why child components do not get re-rendered when reducer returns new state.
Full code on GITHUB
This is my parent component source on git:
import React from "react"
import {connect} from "react-redux"
import {fetchWarehouses} from "../../actions/warehouseActions"
import WarehouseMenu from "./WarehouseMenu"
import WarehouseView from "./WarehouseView"
import WarehouseEdit from "./WarehouseEdit"
#connect((store) => {
return {
warehouses: store.warehouses.warehouses,
selectedWarehouse: store.warehouses.selectedWarehouse,
isSelected: store.warehouses.isSelected,
warehouseCount: store.warehouses.warehouseCount,
}
})
export default class WarehousePage extends React.Component {
componentWillMount() {
this.props.dispatch(fetchWarehouses())
}
render() {
return (
<div className="container-fluid">
<div className="row">
<div className="col-sm-2">
Warehouses ({this.props.warehouseCount}):
</div>
<div className="col-sm-10">
<WarehouseMenu warehouseList={this.props.warehouses} />
</div>
</div>
<div className="col-lg-12">
<WarehouseView test={this.props.isSelected} selectedWarehouse={this.props.selectedWarehouse} />
</div>
<div className="col-lg-12">
<WarehouseEdit />
</div>
</div>
)
}
}
And these are children source on git:
import React from "react"
import store from "../../store"
import {fetchOne} from "../../actions/warehouseActions"
export default class WarehouseMenu extends React.Component {
constructor(props) {
super(props)
}
select(id) {
store.dispatch(fetchOne(id))
}
render() {
const {warehouseList} = this.props.warehouseList
if (!warehouseList) {
return <button className="btn btn-success" key="new_warehouse">+</button>
}
const mappedWarehouses = warehouseList.map(wh => <button onClick={this.select.bind(this, wh.id)} className="btn btn-default" key={wh.id}>{wh.name}</button>)
mappedWarehouses.push(<button className="btn btn-success" key="new_warehouse">+</button>)
return (
<div className="btn-group">
{mappedWarehouses}
</div>
)
}
}
And source on git:
import React from "react"
import store from "../../store"
import {deleteWarehouse, fetchWarehouses} from "../../actions/warehouseActions"
export default class WarehouseView extends React.Component {
constructor(props) {
super(props)
}
render() {
const {test, selectedWarehouse} = this.props
if (!test) {
return null
}
return (
<div className="container-fluid">
<div className="row">
<div className="col-sm-2">
ID
</div>
<div className="col-sm-10">
{selectedWarehouse.id}
</div>
</div>
<div className="row">
<div className="col-sm-2">
Name
</div>
<div className="col-sm-10">
{selectedWarehouse.name}
</div>
</div>
<div className="row">
<div className="col-sm-12">
<button className="btn btn-warning">EDIT</button>
<button onClick={this.deleteWarehouse.bind(this, selectedWarehouse.id)} className="btn btn-danger">DELETE</button>
</div>
</div>
</div>
)
}
deleteWarehouse(id) {
store.dispatch(deleteWarehouse(id))
}
}
So whenever I dispatch deleteWarehouse I want WarehouseMenu to rerender since the state of store.warehouses.warehouses changes. I do not get the expected result. Only WarehousePage rerenders (e.g. store.warehouses.warehouseCount). I've tried #connectint store to child components but did not seem to get the desired result also.
You are not alterning the warehouses property inside your warehouseReducers.js when a DELETE_WAREHOUSE_FULFILLED action is dispatched, but you do alter the warehouseCount
Your delete action:
export function deleteWarehouse(id) {
return function (dispatch) {
axios.delete(`/api/sandy/api/warehouses/${id}`)
.then((response) => {
dispatch({
type: "DELETE_WAREHOUSE_FULFILLED",
payload: null
})
})
.catch((err) => {
})
}
}
never updates the state to remove the deleted warehouse from the state.warehouses array in warehouseReducers.js:
case "DELETE_WAREHOUSE_FULFILLED": {
return {...state,
selectedWarehouse: null,
isSelected: false,
warehouseCount: state.warehouseCount - 1
}
}