how to setState from dynamically created div

I am creating a search bar to search for courses from a mongodb and after returning the courses I have a button with every class to enroll to. How do I set the courseid and student id which I am getting from a redux store auth. I am sending these two to backend. How would I be able to do this.

  class CourseItem extends Component {
  constructor(props) {
    super(props);
    this.state = {
      studentID: "",
      courseID: ""
    };
    this.registerClass = this.registerClass.bind(this);
    this.handleCourse = this.handleCourse.bind(this);
  }
  componentDidMount() {
    this.setState({
      studentID: this.props.auth.user.id
    });
  }
  handleCourse = e => {
    this.setState({ courseID: e.target.value });
  };
  registerClass = e => {
    var data = {
      studentID: this.state.studentID,
      courseID: this.state.courseID
    };
    console.log("from register function", data);

    axios.post("students/registerclass", data).then(res => {
      if (res.status === 200) {
        console.log(res.data);
      }
    });
  };

  render() {
    let classesResult = null;
    if (this.props.class != null) {
      classesResult = this.props.class.map(singleClass => {
        return (
          <ul className="collection with-header" key={singleClass.id}>
            <li className="collection-item">
              <div>
                <p value={singleClass.id} onChange={this.handleCourse}>
                  {singleClass.courseID}
                  {""} {singleClass.courseName}
                </p>
                <span className="secondary-content">
                  <button
                    style={btnColor}
                    onClick={this.registerClass}
                    className="btn btn-flat"
                    type="submit"
                    name="action"
                  >
                    Enroll
                  </button>
                </span>
              </div>
            </li>
          </ul>
        );
      });

1 answer

  • answered 2019-04-15 09:03 Limbo

    I think you need to mapStateToProps() to get the state from the store and update component's local state.

    Check out: https://react-redux.js.org/using-react-redux/connect-mapstate

    function mapStateToProps(state) {
      studentID = state.studentID
      courseID = state.courseID
    }
    
    export default connect(mapStateToProps)(CourseItem)
    

    And then you can use studentID and courseID in your component as props.

    For instance:

    constructor(props) {
      super(props);
      this.state = {
        studentID: "",
        courseID: ""
      };
      this.registerClass = this.registerClass.bind(this);
      this.handleCourse = this.handleCourse.bind(this);
    }
    componentDidMount() {
      this.setState({
        studentID: this.props.auth.user.id
      });
    }
    
    // Added componentWillReceiveProps lifecycle method
    componentWillReceiveProps(nextProps) {
      if (nextProps.studentID) {
        this.setState({
          studentID: nextProps.studentID
        });
      if (nextProps.courseID) {
        this.setState({
          courseID: nextProps.courseID
        });
      }
    }
    handleCourse = e => {
      this.setState({ courseID: e.target.value });
    };
    registerClass = e => {
      var data = {
        studentID: this.state.studentID,
        courseID: this.state.courseID
      };
      console.log("from register function", data);
    
      axios.post("students/registerclass", data).then(res => {
        if (res.status === 200) {
          console.log(res.data);
        }
      });
    };
    
    render() {
      let classesResult = null;
      if (this.props.class != null) {
        classesResult = this.props.class.map(singleClass => {
          return (
            <ul className="collection with-header" key={singleClass.id}>
              <li className="collection-item">
                <div>
                  <p value={singleClass.id} onChange={this.handleCourse}>
                    {singleClass.courseID}
                    {""} {singleClass.courseName}
                  </p>
                  <span className="secondary-content">
                    <button
                      style={btnColor}
                      onClick={this.registerClass}
                      className="btn btn-flat"
                      type="submit"
                      name="action"
                    >
                      Enroll
                    </button>
                  </span>
                </div>
              </li>
            </ul>
          );
        });
    
    
      // ADDED mapStateToProps()
      const mapStateToProps = state => ({
        profileID: state.profileID,
        courseID: state.courseID
      });
    
      export default connect(mapStateToProps)(CourseItem)