【问题标题】:My component that's supposed to show/hide when a button is clicked is not rendering on click单击按钮时应该显示/隐藏的组件在单击时未呈现
【发布时间】:2017-11-28 06:18:54
【问题描述】:

我有一个课程页面,其中包含学生列表作为按钮。单击时,按钮应呈现 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)

我的 ShowStudentInfo 组件

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

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

【问题讨论】:

    标签: reactjs redux react-router react-redux


    【解决方案1】:

    您的 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>
            )
        }
    }
    

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

    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 参数进行比较吗?

    【讨论】:

    • 谢谢你再问一个问题。现在所有学生都显示在按钮下方,而不是所有学生。我怎样才能让它只显示一个?关于您的课程问题,这实际上是课程的ID。我将课程 ID 存储在学生对象中,以检查学生是否在课程内。这对我来说语法/命名很糟糕,我稍后会更改它。
    • 为什么不让按钮成为ShowStudentInfo 的一部分,或者创建一个额外的ToggleStudentInfo 组件来处理它自己的状态,这样你就可以为每个学生做这件事(这样它就会呈现按钮,管理状态,并为每个学生呈现 ShowStudentInfo)
    【解决方案2】:

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

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-21
      • 2013-01-16
      • 1970-01-01
      • 1970-01-01
      • 2017-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多