React:this.setState()在某些函数中工作,而不是在同一组件中的其他函数中工作

问题描述 投票:2回答:1

我正在尝试使用自己的本地状态开发一个简单的小调查组件。我已经在handleChange函数中成功使用了this.setState()来更新选中的单选按钮。我可以看到它在控制台日志和实时页面上工作。但是,如果用户尝试在未完成调查的情况下提交调查,我现在正尝试使用状态来显示模态并突出显示不完整的问题。我必须执行此功能,但状态不会更新。我无法看到我成功更新状态和未更新状态之间的任何差异。

这是我的容器,我控制状态和定义功能。我不认为任何其他代码是相关的,但如果我需要包含其他内容,请告诉我:

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Redirect } from 'react-router'
import { history } from '../history'
import { connect } from 'react-redux'
import _ from 'lodash'
import { postPhq, sumPhq } from '../store'
import { Phq } from '.'
import { UnfinishedModal } from '.'

/**
 * CONTAINER
 */

class PhqContainer extends Component {
  constructor(props) {
    super(props)
    this.state = {
      phq: {
        q1: false, q2: false, q3: false, q4: false, q5: false,
        q6: false, q7: false, q8: false, q9: false, q10: false
      },
      hilitRows: [],
      modalOpen: false
    }
    this.handleChange = this.handleChange.bind(this)
    this.handleSubmit = this.handleSubmit.bind(this)
    this.makeButtons = this.makeButtons.bind(this)
    this.toggleModal = this.toggleModal.bind(this)
  }

  //handles clicks on radio buttons
  handleChange(question, event) {
    var newPhq = this.state.phq
    newPhq[question] = event.target.value
    this.setState({phq: newPhq})
    console.log("radio button", this.state)
  }

  // on submit, first check that PHQ-9 is entirely completed
  // then score the PHQ-9 and dispatch the result to the store
  // as well as posting the results to the database and 
  // dispatching them to the store
  // if the PHQ-9 is not complete, open a modal to alert the user

  handleSubmit(event) {
    event.preventDefault()
    if (this.checkCompletion()) {
      this.props.sumPhq(this.sum())
      this.props.postPhq(this.state.phq)
      this.props.history.push('/results')
    } else {
      console.log(this.unfinishedRows())
      this.toggleModal()
      this.setState({hilitRows: this.unfinishedRows()})
    }
  }

  // returns true if user has completed the PHQ-9 with no missing values
  checkCompletion() {
    return !this.unfinishedRows().length || this.oneToNine().every(val => val === 0)
  }

  unfinishedRows() {
    return Object.keys(_.pickBy(this.state.phq, (val) => val === false))
  }

  oneToNine() {
    var qs1to9 = Object.assign({}, this.state.phq)
    delete qs1to9.q10
    return Object.values(qs1to9)
  }

  toggleModal() {
    console.log("I'm about to toggle the modal", this.state)
    this.setState({modalOpen: !this.state.modalOpen})
    console.log("I toggled the modal", this.state)
  }

  // scores the PHQ-9
  sum() {
    return this.oneToNine
      .map(val => parseInt(val))
      .reduce((total, num) => total + num)
  }

  makeButtons = (num, labels) => {
    var question = 'q' + (num + 1).toString()
    return (
      <div style={rowStyle}>
        {labels.map((label, i) => {
          return (
            <td style={{border: 'none'}}>
              <div className="col radio center-text" >
                <input type="radio"
                  value={i}
                  onChange={(event) => {this.handleChange(question, event)}}
                  checked={this.state.phq[question] && parseInt(this.state.phq[question]) == i} />
                <label>{label}</label>
              </div>
            </td>
          )
        })}
      </div>
    )
  }

  render() {
    return (
      <div>
        <Phq {...this.state} {...this.props}
          handleChange={this.handleChange}
          handleSubmit={this.handleSubmit}
          makeButtons={this.makeButtons} />
        <UnfinishedModal show={this.state.modalOpen} toggleModal={this.toggleModal} />
      </div>
    )
  }
}

const mapDispatch = (dispatch) => {
  return {
    postPhq: (qs) => {
      dispatch(postPhq(qs))
    },
    sumPhq: (total) => {
      dispatch(sumPhq(total))
    }
  }
}

export default connect(() => { return {} }, mapDispatch)(PhqContainer)

const rowStyle = {
  paddingRight: 15,
  borderWidth: 0,
  margin: 0,
  border: 'none',
  borderTop: 0
}

这条线this.setState({phq: newPhq})更新了州。这条线this.setState({hilitRows: this.unfinishedRows()})和这条线this.setState({modalOpen: !this.state.modalOpen})没有。

reactjs
1个回答
0
投票

我在我的项目中遇到了同样的问题,例如setState在某些功能中不起作用,但它适用于同一组件中的其他功能。首先,您应该了解,正如React文档中所提到的,同步触发了setState。因此,您可以检查以下值是否正在更新。

this.setState({mykey: myValue}, () =>  {
    console.log(this.state.mykey);
});

在我的情况下,我试图用输入更新事件onChange的值,在它尝试更新的每个keyUp中,它导致我的问题。所以我试图对该函数使用去抖(延迟),因此它对我来说工作正常。希望这个提示可以帮助你或其他人。

this.myFunction = debounce(this.myFunction,750);
<Input onChange={this.myFunction} />
© www.soinside.com 2019 - 2024. All rights reserved.