I am trying to make simple calendar. In my calendar, I have day, day-names, month and month-names component and all I am accessing it on main calendar. When initial load it will show current month calendar.
Now when I select month from month-name component want to pass to month component and then pass to day component to render dates.
I try to use call back function but it is not helping me out
Whole react component is here https://stackblitz.com/edit/react-ts-z2278r
Day component
import * as moment from 'moment'
import * as React from 'react'
import { showComponent } from '../../../../models'
import { MonthNames } from './'
import styles from './Calendar.module.scss'
interface IDatePickerMonthsProps {
changeMonthComponent: (showComponent: showComponent, monthNo: number) => void
}
interface IDatePickerMonthsState {
dateObject: moment.Moment,
monthNo?: number
}
export class DatePickerMonths extends React.Component<IDatePickerMonthsProps, IDatePickerMonthsState> {
constructor(props: IDatePickerMonthsProps) {
super(props)
this.state = {
dateObject: moment()
}
}
public render() {
const monthPicker =
<div className="datepicker-days">
<table className={styles.table}>
<thead>
<tr>
<th><span className="ms-Icon ms-Icon--ChevronLeft" title="Previous Month" onClick={this.onPrev}></span></th>
<th className={styles["picker-switch"]} data-action="pickerSwitch" colSpan={5} title="Select Month">
{this.year()}
</th>
<th><span className="ms-Icon ms-Icon--ChevronRight" title="Next Month" onClick={this.onNext}></span></th>
</tr>
</thead>
<tbody>
<tr>
<td colSpan={7}>
<MonthNames changeMonthComponent={() => this.showDays(this.state.monthNo)} />
</td>
</tr>
</tbody>
</table>
</div>
return (monthPicker)
}
private year = () => {
return this.state.dateObject.format("Y");
};
private onPrev = () => {
this.setState({
dateObject: this.state.dateObject.subtract(1, "year")
});
};
private onNext = () => {
this.setState({
dateObject: this.state.dateObject.add(1, "year")
});
};
private showDays = (monthNo: number) => {
console.log(monthNo)
this.setState({ monthNo: monthNo })
this.props.changeMonthComponent(showComponent.Days, monthNo)
}
}
Month name component
import * as moment from 'moment'
import * as React from 'react'
import { showComponent } from '../../../../models'
interface IMonthNamesProps {
changeMonthComponent: (showComponent: showComponent, monthNo: number) => void
}
export class MonthNames extends React.Component<IMonthNamesProps, {}> {
private monthshort: string[] = moment.monthsShort();
constructor(props: IMonthNamesProps) {
super(props)
}
public render() {
let monthshortname = this.monthshort.map((month, monthNo) => {
return <span key={monthNo} onClick={() => this.showDays(monthNo)}>{month}</span>;
});
return monthshortname
}
private showDays = (monthNo: number) => {
this.props.changeMonthComponent(showComponent.Days, monthNo)
}
}
Month component
import * as moment from 'moment'
import * as React from 'react'
import { showComponent } from '../../../../models'
import { MonthNames } from './'
import styles from './Calendar.module.scss'
interface IDatePickerMonthsProps {
changeMonthComponent: (showComponent: showComponent, monthNo: number) => void
}
interface IDatePickerMonthsState {
dateObject: moment.Moment,
monthNo?: number
}
export class DatePickerMonths extends React.Component<IDatePickerMonthsProps, IDatePickerMonthsState> {
constructor(props: IDatePickerMonthsProps) {
super(props)
this.state = {
dateObject: moment()
}
}
public render() {
const monthPicker =
<div className="datepicker-days">
<table className={styles.table}>
<thead>
<tr>
<th><span className="ms-Icon ms-Icon--ChevronLeft" title="Previous Month" onClick={this.onPrev}></span></th>
<th className={styles["picker-switch"]} data-action="pickerSwitch" colSpan={5} title="Select Month">
{this.year()}
</th>
<th><span className="ms-Icon ms-Icon--ChevronRight" title="Next Month" onClick={this.onNext}></span></th>
</tr>
</thead>
<tbody>
<tr>
<td colSpan={7}>
<MonthNames changeMonthComponent={() => this.showDays(this.state.monthNo)} />
</td>
</tr>
</tbody>
</table>
</div>
return (monthPicker)
}
private year = () => {
return this.state.dateObject.format("Y");
};
private onPrev = () => {
this.setState({
dateObject: this.state.dateObject.subtract(1, "year")
});
};
private onNext = () => {
this.setState({
dateObject: this.state.dateObject.add(1, "year")
});
};
private showDays = (monthNo: number) => {
console.log(monthNo)
this.setState({ monthNo: monthNo })
this.props.changeMonthComponent(showComponent.Days, monthNo)
}
}
For passing the data from the child component to the parent component, we have to create a callback function in the parent component and then pass the callback function to the child component as a prop. This callback function will retrieve the data from the child component.
To communicate between two independent components in React, you have the flexibility to set up a global event-driven system, or a PubSub system. An event bus implements the PubSub pattern and allows you to listen and dispatch events from components.
export default App; Basically that's how props are passed from component to component in React. As you may have noticed, props are only passed from top to bottom in React application's component hierarchy. There is no way to pass props up to a parent component from a child component.
To pass data from child to parent component in React:Pass a function as a prop to the Child component. Call the function in the Child component and pass the data as arguments. Access the data in the function in the Parent .
See this bit: <MonthNames changeMonthComponent={() => this.showDays(this.state.monthNo)} />
and this bit: this.props.changeMonthComponent(showComponent.Days, monthNo)
The problem there is that the inner component calls the function changeMonthComponent, but the arguments are thrown away by the parent. The MonthNames component needs to do something with the arguments getting passed back up:
<MonthNames changeMonthComponent={(days, monthNo) => this.showDays(monthNo)} />
(Roughly - I'm not digging into all aspects of your code, so I don't know exactly what you want to do with the days parameter that my suggestion is ignoring.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With