子组件保持以前的状态

时间:2017-12-15 09:58:32

标签: reactjs react-redux

您好我有一份学生名单 当我点击学生时,它会将我引导到学生的页面 学生页面是一个组件(查看学生详细信息/学位),其中包含子组件(编辑学位表单)

当我第一次去student1页时,一切正常 如果我按回然后选择student2然后组件呈现正确的学生详细信息,但子组件(编辑学位表格)显示学生1的学位如果我回去再连续两次去学生2它将显示正确。

任何提示? 编辑:实际上容器组件也保持以前的状态 组件,而this.props包含正确的当前状态

import React, { PureComponent } from 'react'
import { connect } from 'react-redux'
import { fetch as fetchStudent } from '../actions/student'
import Title from '../components/Title'
import StudentEditor from './StudentEditor'
//import BatchEditor from './BatchEditor'


class StudentContainer extends PureComponent {
  componentWillMount() {
    this.props.dispatch(fetchStudent(this.props.match.params.id))
    if (this.props){console.log(this.props)}
    this.setState(this.props)

  }
  componentDidMount(){
    this.forceUpdate()
  }
  renderEvaluations(evaluations) {
    const evdata = evaluations.map( evaluation => { 
      let tdstyle= {
        background: evaluation.color,
      };
      return (
        <tr>
          <td>{evaluation.createdAt}</td>
          <td style={tdstyle}>{evaluation.remark}</td>
          <td style={tdstyle}>{evaluation.color}</td>
          <td>{evaluation.userId}</td>
        </tr>);
    });
    return (
      <table border="1">
      <tr>
        <th>Date</th>
        <th>Remark</th>
        <th>Color</th>
        <th>TeacherID</th>
      </tr>
      <tbody>
        {evdata}
      </tbody>
    </table>
    )
  }
  render() {
    if (this.props.student)
    {
      var student = this.props.student;

      console.log(this.state)
      console.log(this.props)
      var childprops= this.state.student;
    return(

      <div className="StudentContainer">
        <header>
          <Title content={`Student: ${student.name}`} />
        </header>

        <main>
          <div className="studentPhoto">
            <img src={student.photo} alt={student.name} />
          </div>
          <div className="studentDetails">
            <div className="title">Name:{student.name}</div>
            <div>Evaluations</div>
            <div className="evaluations">{this.renderEvaluations(student.evaluations)} </div>

          </div>
          <StudentEditor student={student} />
        </main>
      </div>
    )} else { return <div>loading</div> }
  }
}

const mapStateToProps = ({ student }) => ({ ...student })

export default connect(mapStateToProps)(StudentContainer)

编辑

import React, { PureComponent } from 'react'
import { connect } from 'react-redux'
import 'medium-editor/dist/css/medium-editor.css'
import 'medium-editor/dist/css/themes/default.css'
import updateStudent from '../actions/student/update'
import Title from '../components/Title'



class StudentEditor extends PureComponent {
  constructor(props) {
    super()

    this.state = props.student
    this.state.currentUser = "5a3151c868720b1d4cef1b48"

  }

  updateName(event) {
    if (event.keyCode === 13) {
      event.preventDefault()
      this.refs.name.medium.elements[0].focus()
    }
    this.setState({
      name: this.refs.name.value
    })
  }
  updateRemark(event) {

    const index = event.target.id
    console.log(index)
    if (event.keyCode === 13) {
      event.preventDefault()
      this.refs.remark.medium.elements[0].focus()
    }

    const evaluat = this.state.evaluations
    evaluat[index].remark = event.target.value
    console.log(this.state)
    this.setState({evaluations: evaluat })
    console.log(this.state)
    //const evaluation = this.state.evaluations;
    //this.state.evaluations[index].remark = this.refs.remark.value;

    this.forceUpdate();

    /*
    this.setState({
      this.state.evaluations[0].remark: this.refs.remark.value
    })*/
  }
  updateColor(event) {
    const index = event.target.id
    if (event.keyCode === 13) {
      event.preventDefault()
      this.refs.color.medium.elements[0].focus()
    }
    //const evaluation = this.state.evaluations;
    //this.setState( {evaluations[index]: event.target.value}) //= event.target.value;

    const evaluat = this.state.evaluations
    evaluat[index].color = event.target.value;

    this.setState({evaluations: evaluat })
    this.forceUpdate();
  }

  updatePhoto(event) {
    if (event.keyCode === 13) {
      event.preventDefault()
      this.refs.photo.medium.elements[0].focus()
    }
    this.setState({
      photo: this.refs.photo.value
    })
  }

  addEvaluation() {
    const newremark= this.refs.newremark.value
    const newcolor= this.refs.newcolor.value
    const newuserId= "5a3151c868720b1d4cef1b48"
    let newarray= this.state.evaluations.slice()
    let neweva= {remark: newremark, color: newcolor, userId:newuserId}
    newarray.push(neweva)
    const student= {
      ...this.state
    }
    student.evaluations=newarray
    this.setState(student)
    this.props.save(student)
    this.forceUpdate()


  }
  saveStudent() {
    console.table(this.state)

    const student= {
      ...this.state
    }

    console.table(student)

    this.props.save(student)
  }
  renderEvaluationsForm(){
    if(this.state.evaluations){
      const rendered = this.state.evaluations.map((evaluation,index) => {
      if (evaluation.userId === this.state.currentUser){
        return (
        <div>
        <input
          type="text"
          ref="remark"
          className="remark"
          placeholder="remark"
          onChange={this.updateRemark.bind(this)}
          value={this.state.evaluations[index].remark} 
          id={index} />
          <select
          ref="color"
          className="color"
          onChange={this.updateColor.bind(this)}
          value={this.state.evaluations[index].color}
          id={index}>
          <option value="green">green </option>
          <option value="orange">orange </option>
          <option value="red">red </option>
          </select>
          </div>
      );}});
      return rendered;
    }
  }

  render() {

    return (
      <div className="editor">
      <header>
        <Title content="Modify Name or Photo" />
      </header>
        <label>Student's Name:</label>
        <input
          type="text"
          ref="name"
          className="name"
          placeholder="name"
          onChange={this.updateName.bind(this)}
          onKeyUp={this.updateName.bind(this)}
          value={this.state.name} />
          <label>Student's Photo:</label>
          <input
          type="text"
          ref="photo"
          className="photo"
          placeholder="photo"
          onChange={this.updatePhoto.bind(this)}
          onKeyUp={this.updatePhoto.bind(this)} 
          value={this.state.photo}/>
          <br /><br />
          <div> Modify Evaluations </div><br />
        {this.renderEvaluationsForm()}
        <div className="actions">
          <button className="primary" onClick={this.saveStudent.bind(this)}>Update</button><br />
        </div>
        <br />
        <div> Add new Evaluation </div><br />
        <label>Evaluation Remark:</label>
        <input
          type="text"
          ref="newremark"
          className="newremark"
          placeholder="Add remark"
          />
          <label>Evaluation Color:</label>
          <select
          type="text"
          ref="newcolor"
          className="newcolor"
          >
          <option value="green">green</option>
          <option value="orange">orange</option>
          <option value="red">red</option>
          </select>
          <div className="actions">
          <button className="primary" onClick={this.addEvaluation.bind(this)}>Add Evaluation</button><br />
          </div>
      </div>

    )
  }
}

const mapDispatchToProps = { save: updateStudent }

export default connect(null, mapDispatchToProps)(StudentEditor)

1 个答案:

答案 0 :(得分:1)

请注意,您需要在StudentContainer组件中实现componentWillReceiveProps(nextProps)方法并相应地设置状态。在组件呈现在DOM中之前,只会调用componentWillMount()方法一次。

之后,任何道具更改componentWillReceiveProps()生命周期钩子将被React调用