单击按钮时应该显示/隐藏的组件不会在单击时呈现

时间:2017-06-25 01:01:29

标签: reactjs redux react-router react-redux

我有一个课程页面,其中包含学生列表作为按钮。单击时,该按钮应呈现ShowStudentInfo,但嵌套在内部时,我的ShowStudentInfo组件不会在单击时呈现(如果state.isClicked)。在条件之外它工作正常,但我需要条件,否则一切都会出现在课程页面渲染上。

主要课程组件



import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import * as actions from '../actions/index';
import { Redirect } from 'react-router';
import { Link } from 'react-router-dom';
import ShowStudentInfo  from '../ShowStudentInfo/ShowStudentInfo'

class CoursePage extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      course: {},
      student: {},
      isClicked: false
    };
    console.log(this.props.match.params.cuid)
    this.onClick = this.onClick.bind(this)
  }

  onClick(event) {
    event.preventDefault()
    console.log(this.state.isClicked)
    this.setState({
      isClicked: !this.state.isClicked
    })
  }
  componentDidMount() {
    this.props.dispatch(actions.getCourse(this.props.match.params.cuid));
    this.props.dispatch(actions.getStudents());
  }

  render() {
    let studentList = this.props.student
    const students = Object.keys(studentList).map(student => studentList[student])
    const currentStudents = students.map(student => {
      if ((this.props.match.params.cuid) == student.courses) {
        return (
          <p>
            <button className="students" id={student._id} onClick={this.onClick}>{student.firstName} {student.lastName}</button>
          </p>
        )
        if (this.state.isClicked) {
          return (
            <div className="student-info">
              <ShowStudentInfo firstName={student.firstName}
              lastName={student.lastName} phoneNumber={student.phoneNumber} />
        </div>
      )
        }
      }
    })
    return (
      <div>
        <h1>{this.props.course.name}</h1>
        <Link to={`/addStudent/${this.props.match.params.cuid}`}> Add a new student</Link>
        <div className="studentList">Your students{currentStudents} </div>
      </div>
    );
  }
}
const mapStateToProps = (state, props) => {
  return {
    course: state.course.course,
    student: state.student.students
  }
}

export default connect(mapStateToProps)(CoursePage)
&#13;
&#13;
&#13;

我的ShowStudentInfo组件

&#13;
&#13;
import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import * as actions from '../actions/index';
import { Redirect } from 'react-router';
import { Link } from 'react-router-dom';

class ShowStudentInfo extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      student: {
        firstName: '',
        lastName: '',
        phoneNumber: ''
      },
      isClickedEdit: false,
      isClickedDelete: false
    }
    this.isClickedEdit = this.isClickedEdit.bind(this)
    this.isClickedDelete = this.isClickedDelete.bind(this)
  }
  isClickedEdit(event) {
    this.setState({
      isClickedEdit: true
    })
  }
  isClickedDelete(event) {
    this.setState({
      isClickedDelete: true
    })
  }
  render() {
    return (
      <div className="student-info-container">
        <p>Name: {this.props.firstName} {this.props.lastName}</p>
        <p>Phone Number: {this.props.phoneNumber}</p>
      </div>
    )
  }
}
&#13;
&#13;
&#13;

if (this.state.isClicked) {
      return (
        <div className="student-info">
          <ShowStudentInfo firstName={student.firstName}
          lastName={student.lastName} phoneNumber={student.phoneNumber} />
    </div>
  )
    }

是最重要的部分,在没有onClick条件的情况下,信息正常呈现。

2 个答案:

答案 0 :(得分:2)

你的map函数包含2个返回函数,而第一个返回将使它转到当前迭代过程中的下一个项目

if ((this.props.match.params.cuid) == student.courses) {
    return (
      <p>
        <button className="students" id={student._id} onClick={this.onClick}>{student.firstName} {student.lastName}</button>
      </p>
    )
    // this will never hit in case the previous statement is evaluates to true
    if (this.state.isClicked) {
      return (
        <div className="student-info">
          <ShowStudentInfo firstName={student.firstName}
          lastName={student.lastName} phoneNumber={student.phoneNumber} />
        </div>
        )
    }
}

为了实现你想做的事情,(我猜你希望它作为第一个返回声明的一部分),你可以这样做

if ((this.props.match.params.cuid) == student.courses) {
    return (
      <p>
        <button className="students" id={student._id} onClick={this.onClick}>{student.firstName} {student.lastName}</button>
        { this.state.isClicked && <div className="student-info">
          <ShowStudentInfo firstName={student.firstName}
          lastName={student.lastName} phoneNumber={student.phoneNumber} />
        </div> }
      </p>
      )
}

警告:这会将学生信息显示为屏幕上所有学生的p标记的一部分,我不会看到您限制显示所点击学生的用户信息的位置。

另外注意,你确定要用cuid参数来比较课程对象吗?

答案 1 :(得分:0)

这只是你逻辑上的一点点重构:)希望它对你有所帮助。

import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import * as actions from '../actions/index';
import { Redirect } from 'react-router';
import { Link } from 'react-router-dom';
import ShowStudentInfo from '../ShowStudentInfo/ShowStudentInfo'

class CoursePage extends React.Component {

  state = {
    course: {},
    student: {},
    isClicked: false
  };

  onClick = (event) => {
    event.preventDefault()
    console.log(this.state.isClicked)
    this.setState({
      isClicked: !this.state.isClicked
    })
  }

  getCurrentStudents = (students) => {
    const { match } = this.props
    const { isClicked } = this.state

    return students.map(student => {
      if (match.params.cuid == student.courses) {
        return (
          <div>
            <p><button className="students" id={student._id} onClick={this.onClick}>
              {student.firstName} {student.lastName}
            </button></p>
            {isClicked && this.getStudentInfo(student) }
          </div>
        )
      }
    })
  }

  getStudentInfo = (student) => (
    <div className="student-info" >
      <ShowStudentInfo
        firstName={student.firstName}
        lastName={student.lastName}
        phoneNumber={student.phoneNumber} />
    </div>
  )


  componentDidMount() {
    let { match, dispatch } = this.props
    dispatch(actions.getCourse(match.params.cuid));
    dispatch(actions.getStudents());
  }

  render() {
    let { studentList, match, course } = this.props
    const students = Object.keys(studentList).map(student => studentList[student])
    const currentStudents = this.getCurrentStudents(students)

    return (
      <div>
        <h1>{course.name}</h1>
        <Link to={`/addStudent/${match.params.cuid}`}> Add a new student</Link>
        <div className="studentList">Your students{currentStudents} </div>
      </div>
    );
  }
}

const mapStateToProps = (state, props) => {
  return {
    course: state.course.course,
    student: state.student.students
  }
}

export default connect(mapStateToProps)(CoursePage)