मेरे पास एक मूल घटक है जिसके अंदर टाइमर घटक है। टाइमर 15 मिनट से शुरू होता है और 0 तक उलटी गिनती करता है। जब मेरा टाइमर 0 के रूप में समय दिखाता है तो मैं सबमिट बटन ईवेंट ट्रिगर करना चाहता हूं, सबमिट बटन क्विज़ कंपोनेंट के अंदर है (क्विज़ कंपोनेंट पेरेंट कंपोनेंट का चाइल्ड कंपोनेंट भी है)। मैंने पाया कि जब p टैग बदलता है तो शायद मैं MutationObserver का उपयोग कर सकता हूं। मुझे यकीन नहीं है कि यह सही और एकमात्र दृष्टिकोण है या इसे हासिल करने का बेहतर तरीका है।

अभिभावक घटक:

import React, { Component } from 'react';
import '../css/App.css'
import Quiz from './Quiz';
import Timer from './Timer';
import { connect } from 'react-redux';
import { ActionTypes } from '../redux/constants/actionTypes';
import { saveQuizAll, getQuizIndex } from '../commonjs/common.js';

const mapStateToProps = state => { return { ...state.quiz, ...state.quizAll } };

const mapDispatchToProps = dispatch => ({
  onQuizLoad: payload => dispatch({ type: ActionTypes.QuizLoad, payload }),
  onQuizChange: payload => dispatch({ type: ActionTypes.QuizAnswerAll, payload }),
  onPagerUpdate: payload => dispatch({ type: ActionTypes.PagerUpdate, payload })
});

class QuizContainer extends Component {
  state = {
    quizes: [
      { id: 'data/class1.json', name: 'Class 1' },
      { id: 'data/class2.json', name: 'Class 2' },
      { id: 'data/class3.json', name: 'Class 3' },
      { id: 'data/class4.json', name: 'Class 4' },
    ],
    quizId: 'data/class1.json'
  };

  pager = {
    index: 0,
    size: 1,
    count: 1
  }

  componentDidMount() {
    console.log('componentDidMount');
    this.load(this.state.quizId);
  }

  load(quizId, isValReload) {
    console.log('In load');
    let url = quizId || this.props.quizId;
    if (isValReload) {
      let quiz = this.props.quizAll.find(a => url.indexOf(`${a.id}.`) !== -1);
      console.log('In load quiz : ', quiz);
      this.pager.count = quiz.questions.length / this.pager.size;
      this.props.onQuizLoad(quiz);
      this.props.onPagerUpdate(this.pager);
    }
    else {
      fetch(`../${url}`).then(res => res.json()).then(res => {
        let quiz = res;
        quiz.questions.forEach(q => {
          q.options.forEach(o => o.selected = false);
        });
        quiz.config = Object.assign(this.props.quiz.config || {}, quiz.config);
        this.pager.count = quiz.questions.length / this.pager.size;
        this.props.onQuizLoad(quiz);
        this.props.onPagerUpdate(this.pager);
      });
    }
  }

  //This event implements restriction to change class without finishing curretnly selectd class
  onClassClick = (e) => {
    let qus = this.props.quiz.questions;
    // console.log(qus);
    let isNotAllAns = qus.some((q, i) => {
      var isNot = false;
      if (q.answerType.id !== 3 && q.answerType.id !== 4) {
        isNot = (q.options.find((o) => o.selected === true)) === undefined;
      }
      else {
        // console.log('q', q);
        isNot = ((q.answers === "" || q.answers.length === 0));
      }
      return isNot;
    });
    if (isNotAllAns) {
      alert('Please complete the quiz.');
      e.stopPropagation();
    }
  }

  /*
  saveQuizAll(_quizAll, _quiz) {
    let allQuiz = [];
    // , _quizAll, _quiz;
    // if (true) {
    //   _quiz = this.quiz;
    //   _quizAll = this.quizAll;
    // }

    console.log(this, _quiz, _quizAll);
    if (_quiz.questions.length !== 0) {

      if (_quizAll.length !== undefined) {
        console.log('Not Initial Setup Splice', _quiz.id);
        allQuiz = _quizAll;
        const qIndex = this.getQuizIndex(_quiz.id.toString());
        if (qIndex > -1) {
          allQuiz.splice(qIndex, 1, _quiz);
        }
        else {
          allQuiz.splice(_quizAll.length, 0, _quiz);
          // allQuiz.splice(this.props.quizAll.length-1, 0, this.props.quizAll, this.props.quiz);
        }
      }
      else {
        allQuiz[0] = _quiz;
      }
      return allQuiz;
      // if (true) {
      //   this.onQuizChange(allQuiz);
      // }
    }
  }
  */

  onChange = (e) => {
    // console.log(this.props.quizAll, this.props.quizAll.length);
    let allQuiz = [];
    allQuiz = saveQuizAll(this.props.quizAll, this.props.quiz);

    //below code converted into saveQuizAll funstion
    /*
    if (this.props.quizAll.length !== undefined) {
      console.log('Not Initial Setup Splice', this.props.quiz.id);
      allQuiz = this.props.quizAll;
      const qIndex = this.getQuizIndex(this.props.quiz.id.toString());
      if (qIndex > -1) {
        allQuiz.splice(qIndex, 1, this.props.quiz);
      }
      else {
        allQuiz.splice(this.props.quizAll.length, 0, this.props.quiz);
        // allQuiz.splice(this.props.quizAll.length-1, 0, this.props.quizAll, this.props.quiz);
      }
    }
    else {
      allQuiz[0] = this.props.quiz;
    }
    */

    // console.log('allQuiz Out - ', allQuiz);
    this.props.onQuizChange(allQuiz);
    console.log('Check QuizAll - ', this.props.quizAll);
    const aQuiz = JSON.parse(JSON.stringify(this.props.quizAll));
    this.setState({ quizId: e.target.value });
    if (aQuiz.length !== undefined && getQuizIndex(this.props.quizAll, e.target.value) > -1) {
      // console.log(aQuiz.findIndex(a => e.target.value.indexOf(`${a.id}.`) !== -1));
      this.load(e.target.value, true);
    }
    else {
      this.setState({ quizId: e.target.value });
      this.load(e.target.value, false);
    }
  }

  // getQuizIndex(qID) {
  //   return this.props.quizAll.findIndex(a => (qID.indexOf(`${a.id}.`) !== -1 || qID.indexOf(`${a.id}`) !== -1));
  // }

  render() {
    return (
      <div className="container">
        <header className="p-2">
          <div className="row">
            <div className="col-6">
              <h3>DADt Application</h3>

            </div>
            <div className="col-6 text-right">
              <label className="mr-1">Select Quiz:</label>
              <select onChange={this.onChange} onClick={this.onClassClick}>
                {this.state.quizes.map(q => <option key={q.id} value={q.id}>{q.name}</option>)}
              </select>
            </div>
          </div>
        </header>
        <Timer duration={900}/>
        <Quiz quiz={this.state.quiz} quizId={this.state.quizId} saveAll={saveQuizAll} mode={this.state.mode} />
      </div>
    );
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(QuizContainer);

यह रहा मेरा टाइमर घटक

    import React, { Component } from 'react'

class Timer extends Component {
    constructor(props) {
        super(props);
        this.state = {
            seconds: 0
        };
    }

    tick() {
        this.setState((prevState) => ({
            seconds: prevState.seconds + 1
        }));
    }

    componentDidMount() {
        this.interval = setInterval(() => this.tick(), 1000);
    }

    componentWillUnmount() {
        clearInterval(this.interval);
    }

    render() {
        const { duration } = this.props;
        let timeLeft = duration - this.state.seconds;
        timeLeft = Number(timeLeft);
        let minutes = Math.floor(timeLeft % 3600 / 60);
        let seconds = Math.floor(timeLeft % 3600 % 60);

        let minutesDisplay = minutes > 0 ? minutes + (minutes === 1 ? " : " : " : ") : "";
        let secondsDisplay = seconds > 0 ? seconds + (seconds === 1 ? "" : "") : "";

    return <p className="badge badge-success">Time Left: {minutesDisplay}{secondsDisplay}</p>;
    }
}

export default Timer;

प्रश्नोत्तरी घटक:

import React, { Component } from 'react';
import { ActionTypes } from '../redux/constants/actionTypes';
import Review from './Review';
import Questions from './Questions';
import Result from './Result';
import { connect } from 'react-redux';
// import { saveQuizAll } from '../commonjs/common.js';


const mapStateToProps = state => { return { ...state.quiz, ...state.mode, ...state.pager, ...state.quizAll } };

const mapDispatchToProps = dispatch => ({
    onSubmit: payload => dispatch({ type: ActionTypes.QuizSubmit, payload }),
    onQuizChange: payload => dispatch({ type: ActionTypes.QuizAnswerAll, payload }),
    onPagerUpdate: payload => dispatch({ type: ActionTypes.PagerUpdate, payload })
});

class Quiz extends Component {
    move = (e) => {
        let id = e.target.id;
        let index = 0;
        if (id === 'first')
            index = 0;
        else if (id === 'prev')
            index = this.props.pager.index - 1;
        else if (id === 'next') {
            index = this.props.pager.index + 1;
          }
        else if (id === 'last')
            index = this.props.pager.count - 1;
        else
            index = parseInt(e.target.id, 10);

        if (index >= 0 && index < this.props.pager.count) {
            let pager = {
                index: index,
                size: 1,
                count: this.props.pager.count
            };
            this.props.onPagerUpdate(pager);
        }
    }

    saveStore(e) {
      let allQuiz = [];
      console.log(this, e);
      allQuiz = this.props.saveAll(e.props.quizAll, e.props.quiz);
      console.log(allQuiz);
      this.props.onQuizChange(allQuiz);
    }

    setMode = (e) => this.props.onSubmit(e.target.id);

    // setMode(e) {
    //   console.log('in mode',e);this.props.onSubmit(e.target.id);
    // }

    renderMode() {
      console.log('Inside here', this.props.mode);
        if (this.props.mode === 'quiz') {
            return (<Questions move={this.move} />)
        } else if (this.props.mode === 'review') {
            return (<Review quiz={this.props.quiz} move={this.move} />)
        } else {
            console.log('Before Results');
            const divSel = document.querySelector('div.col-6.text-right');
            // console.log('divSel', divSel);
            if (divSel) {
              divSel.style.display = "none";
            }
            return (<Result questions={this.props.quizAll || []} />)
        }
    }

    render() {
        return (
            <div>
                {this.renderMode()}
                {(this.props.mode !== 'submit') &&
                    <div>
                        <hr />
                        <button id="quiz" className="btn btn-primary" onClick={this.setMode}>Quiz</button>
                        <button id="review" className="btn btn-primary" onClick={this.setMode}>Review</button>
                        <button id="submit" className="btn btn-primary" onClick={(e) => {this.setMode(e); this.saveStore(this)}}>Submit Quiz</button >
                    </div >}
            </div>
        )
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Quiz);
0
Aditi Lamkhede 18 सितंबर 2020, 09:18

3 जवाब

सबसे बढ़िया उत्तर

मुझे लगता है कि आपके पास दो दृष्टिकोण हो सकते हैं।

1. "प्रतिक्रिया" तरीका

मूल घटक में:

// ...
constructor(props) {
  // ...
  this.state = {
    timeExpired: false
  };
}
    
const onTimeExpired = () => {
  this.setState({timeExpired: true});
}
   
// ...
    
render() {
  return (
    <div className="container">
      { // ... }
      <Timer duration={900} onTimeExpired={onTimeExpired}/>
      <Quiz quiz={this.state.quiz} quizId={this.state.quizId} saveAll={saveQuizAll} mode={this.state.mode} triggerSubmit={this.state.timeExpired} />
      </div>
    );
}

टाइमर घटक में:

// ...

componentDidUpdate() {
  if (this.state.seconds === this.props.duration) {
    this.props.onTimeExpired();
  }
}

// ...

प्रश्नोत्तरी घटक में:

// ...

componentDidUpdate() {
  if (this.props.triggerSubmit) {
    // Do whatever you do on submit
  }
}

// ...

2. "त्वरित और गंदा" तरीका:

टाइमर घटक में

// ...

componentDidUpdate() {
  if (this.state.seconds === this.props.duration) {
    const quizForm = document.getElementById('quizFormId');
    quizForm && quizForm.submit();
  }
}

// ...
0
secan 18 सितंबर 2020, 10:39

अपने टाइमर घटक में एक प्रोप विधि onTimeFinished प्रदान करें। फिर अपने रेंडर फंक्शन में आप जोड़ सकते हैं

{ !(this.props.duration-this.state.seconds) && this.props.onTimeFinished() }

संदर्भ: प्रतिक्रिया सशर्त प्रतिपादन

0
ajay.16nk 18 सितंबर 2020, 10:09

ये कोशिश करें:

मूल घटक:

// state
state = {
    triggerSubmit: false
}  

// functions
doSubmit = () => {
    this.setState({ triggerSubmit: true });
}
resetSubmit = () => {
    this.setState({ triggerSubmit: false });
}  

// jsx
<Timer duration={900} doSubmit={this.doSubmit} />
<Quiz 
    quiz={this.state.quiz}
    quizId={this.state.quizId}
    saveAll={saveQuizAll}
    mode={this.state.mode}
    resetSubmit={this.resetSubmit}
    triggerSubmit={this.state.triggerSubmit} />

टाइमर घटक:

// function
doSubmit = (timeLeft) => {
  if (timeLeft === 0) {
    this.props.doSubmit();
  }
}  

// jsx
<p className="badge badge-success"
   onChange={() => {this.doSubmit(timeLeft)}>
   Time Left: {minutesDisplay}{secondsDisplay}
</p>

प्रश्नोत्तरी घटक:

// state
state = {
    triggerSubmit: this.props.triggerSubmit
}  

// function
triggerSubmit = () => {
    if (this.state.triggerSubmit) {
       your trigger submit code here...
       this.props.resetSubmit();
    }
}
0
user12751387user12751387 18 सितंबर 2020, 10:15