0
votes

Hi I am trying to learn React with Typescript.

I have encountered a problem whereby properties are not being initialised in a child component that is created from parent component render method.

Within the render method of the parent component the console log prints the list items. If I uncomment the constructor of the child component I can see that the properties are empty.

What is the correct way in ReactJs to render a child component and pass properties?

Solved Solved this! The problem was in the code for RestDataSource.getCourses(). This was not transforming to properties model. The JSON from the Rest API returned included CourseID and CourseName properties. The react child component Course included properties courseID and courseName. Fixed by ensuring properties exactly matched.

CourseList.ts (Parent)

import * as React from 'react';

import Course from './Course';
import { CourseProps } from './Course';
import { RestDataCourse } from '../data/RestDataCourse';

type CourseListProps = {};

type CourseListState = {
  courses: Array<CourseProps>;
};

export default class CourseList extends React.Component<
  CourseListProps,
  CourseListState
> {
  constructor(props: CourseListProps) {
    super(props);
    this.state = { courses: new Array<CourseProps>() };
  }

  async componentDidMount(): Promise<void> {
    console.log('CourseList::componentDidMount');

    const dataSource: RestDataCourse = new RestDataCourse();
    const coursesList: Array<CourseProps> = await dataSource.getCourses();

    this.setState({ courses: coursesList });
  }

  async componentWillUnmount(): Promise<void> {
    console.log('CourseList::componentWillUnmout');
  }

  public render(): JSX.Element {
    console.log('CourseList::render => ' + JSON.stringify(this.state.courses));
    return (
      <div>
        {this.state.courses.map(c => (
          <Course
            key={c.courseID}
            courseID={c.courseID}
            courseName={c.courseName}
          />
        ))}
      </div>
    );
  }
}

Course.ts (Child)

import * as React from 'react';

export interface CourseProps {
  courseID: string;
  courseName: string;
}

export default class Course extends React.Component<CourseProps, {}> {
  // constructor(props: CourseProps) {
  //   super(props);
  //   console.log(`Course::constructor => ${JSON.stringify(props)}`);
  // }

  componentDidMount(): void {
    console.log('Course::componentDidMount');
  }

  componentWillUnmount(): void {
    console.log('Course::componentWillUnmout');
  }

  public render(): JSX.Element {
    console.log(
      JSON.stringify(`Course::render => ${JSON.stringify(this.props)}`),
    );
    return (
      <div>
        Course render
        {this.props.courseID}
        {this.props.courseName}
      </div>
    );
  }
}

1

1 Answers

0
votes

Solved this! The problem was in the code for RestDataSource.getCourses(). This was not transforming to properties model. The JSON properties returned from the Rest API included CourseID and CourseName properties. The react child component Course included properties courseID and courseName. Fixed by ensuring properties exactly matched.