Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing Data between react components

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)
  }
}
like image 402
Milind Avatar asked Oct 15 '22 07:10

Milind


People also ask

How do you pass data from one component to another in React?

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.

How do you pass data between two independent components in React?

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.

How do you pass data using props in React?

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.

How do you pass data from child component to parent component in React?

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 .


1 Answers

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.)

like image 50
see sharper Avatar answered Nov 03 '22 03:11

see sharper