我正在尝试在React中实现一个处理程序,以用于SurveyJS中实现的调查。这是针对多项选择题,其答案可能类似于“以上皆非”或“不愿回答”。如果选择了这些答案之一,则所有其他答案都将被清空,如果选择了其他答案,则应清除这些复选框。我可以单独使用这两个选项中的任何一个,但都存在一个选项都存在的问题,特别是在两个特殊选项之间来回切换时。
我认为正在发生的事情是,当一个答案触发处理程序并取消选中另一个复选框时,它将再次触发处理程序。我的解决方案是设置一个状态,该状态指示处理程序何时处于此过程的中间,而此时不再执行此操作。
我在这里有一个JS解决方案:https : //github.com/surveyjs/editor/issues/125-以下是我尝试将其转换为React的尝试。(仅包括代码的相关部分。)
但是,在编译时,会出现以下错误:
[加载程序]中的错误。/src/components/Survey/SurveyContainer.tsx:55:19TS2339:类型’Readonly <{}>’不存在属性’ValueChanging’。
我找不到有关此特定错误的任何信息。对该状态的其他引用(即我在其中设置的位置)正在工作。为什么我看不懂?
谢谢!
零件:
import * as React from 'react'; import { Component } from 'react'; import { Survey, surveyStrings } from 'survey-react'; import 'whatwg-fetch'; import Marked from '../Marked'; import * as style from './style'; interface Props { surveyJson: object; complete: boolean; resultMarkdown: string; surveyTitle: string; sendSurveyAnswers: (answers: object[]) => void; noneOfTheAboveHandler: (survey: object, options: object) => void; } Survey.cssType = 'standard'; surveyStrings.progressText = '{0}/{1}'; surveyStrings.emptySurvey = ''; export default class SurveyComponent extends Component<Props, {}> { render() { const { surveyJson, sendSurveyAnswers, complete, surveyTitle, resultMarkdown, noneOfTheAboveHandler } = this.props; return ( <style.Wrapper> { surveyJson && (!complete) && <style.SurveyWrapper> <style.SurveyTitle>{ surveyTitle }</style.SurveyTitle> <style.Survey> <Survey onValueChanged={ noneOfTheAboveHandler } css={ style.surveyStyles } json={ surveyJson } onComplete={ sendSurveyAnswers } /> </style.Survey> </style.SurveyWrapper> } { complete && <style.Results> <Marked content={resultMarkdown} /> </style.Results> } </style.Wrapper> ); } }
容器:
import * as React from 'react'; import { Component } from 'react'; import { connect } from 'react-redux'; import SurveyComponent from './SurveyComponent'; interface Props { id: string; surveyJson: object; complete: boolean; resultMarkdown: string; surveyTitle: string; getSurveyQuestions: (id: string) => void; sendSurveyAnswers: (answers: object[]) => void; noneOfTheAboveHandler: (survey: object, options: object) => void; clearSurvey: () => void; } class SurveyContainer extends Component<Props, {}> { constructor(props) { super(props); this.state = { ValueChanging: false }; } componentDidMount() { this.noneOfTheAboveHandler = this.noneOfTheAboveHandler.bind(this); this.props.getSurveyQuestions(this.props.id); } specialValueSelected(options, specialValue) { const { question } = options; const prevValue = question.prevValue; const index = options.value.indexOf(specialValue); this.setState({ ValueChanging: true }); //has special value selected if(index > -1) { //special value was selected before if(prevValue.indexOf(specialValue) > -1) { var value = question.value; value.splice(index, 1); question.value = value; } else { //special value select just now question.value = [specialValue]; } } this.setState({ ValueChanging: false }); return index > -1; } noneOfTheAboveHandler(survey, options) { const none = 'NA'; const preferNotToAnswer = 'PN'; const { question } = options; if(this.state.ValueChanging) { return; } if (!question || question.getType() !== 'checkbox') { return; } if (!question.prevValue || !options.value) { question.prevValue = options.value; return; } if (!this.specialValueSelected(options,none)) { this.specialValueSelected(options,preferNotToAnswer); } question.prevValue = options.value; } componentWillUnmount() { this.props.clearSurvey(); } render() { return ( <SurveyComponent noneOfTheAboveHandler={this.noneOfTheAboveHandler} {...this.props} /> ); } } const mapStateToProps = (state, ownProps) => ({ surveyJson: state.survey.json, answers: state.survey.answers, resultMarkdown: state.survey.resultMarkdown, complete: state.survey.complete, surveyTitle: state.page && state.page.data ? state.page.data.title : '' }); const mapDispatchToProps = dispatch => ({ getSurveyQuestions: id => dispatch({ type: 'GET_SURVEY_QUESTIONS', id }), sendSurveyAnswers: answers => dispatch({ type: 'SEND_SURVEY_ANSWERS', answers: answers.data }), clearSurvey: () => dispatch({ type: 'CLEAR_SURVEY' }) }); export default connect( mapStateToProps, mapDispatchToProps )(SurveyContainer);
造成这种情况的最可能原因是,您没有在其类定义中指定组件状态的类型,因此默认为{}。您可以通过声明props和state类型的接口,并将它们作为React.Component的类型参数提供,来修复它:
{}
interface MyComponentProps { /* declare your component's props here */ } interface MyComponentState { ValueChanging : boolean } class MyComponent extends React.Component<MyComponentProps, MyComponentState> { constructor(props) { ...
您可以在<和之间直接提供类型>,但是使用接口通常会导致代码更具可读性并促进重用。为了避免与组件混淆,将小写标识符用于props和state的属性也是一个好主意。
<
>