小编典典

类型“ Readonly <{}>”上不存在“ ValueChanging”

reactjs

我正在尝试在React中实现一个处理程序,以用于SurveyJS中实现的调查。这是针对多项选择题,其答案可能类似于“以上皆非”或“不愿回答”。如果选择了这些答案之一,则所有其他答案都将被清空,如果选择了其他答案,则应清除这些复选框。我可以单独使用这两个选项中的任何一个,但都存在一个选项都存在的问题,特别是在两个特殊选项之间来回切换时。

我认为正在发生的事情是,当一个答案触发处理程序并取消选中另一个复选框时,它将再次触发处理程序。我的解决方案是设置一个状态,该状态指示处理程序何时处于此过程的中间,而此时不再执行此操作。

我在这里有一个JS解决方案:https :
//github.com/surveyjs/editor/issues/125-以下是我尝试将其转换为React的尝试。(仅包括代码的相关部分。)

但是,在编译时,会出现以下错误:

[加载程序]中的错误。/src/components/Sur​​vey/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);

阅读 422

收藏
2020-07-22

共1个答案

小编典典

造成这种情况的最可能原因是,您没有在其类定义中指定组件状态的类型,因此默认为{}。您可以通过声明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的属性也是一个好主意。

2020-07-22