简体   繁体   English

在渲染函数中调用函数-ReactJS?

[英]Calling a function inside render function - ReactJS?

Ok so I am making a "buzzfeed" quiz generator and I am having an issue with a piece of my form. 好的,所以我正在制作“ buzzfeed”测验生成器,但是我的表单存在问题。 So for each question made there are two different parts, a "Question" and the "Answers". 因此,对于每个提出的问题,都有两个不同的部分,即“问题”和“答案”。 There will always be 4 answers but I want to keep track of which Answers are checked later so I would like to give each answer a unique id "question" + questionNum + "Answer" + answerNum or "question" + questionNum + "Answer" + i So I made this answersGenerator function that is supposed to give me 4 unique answer choice fill ins for the user to input answers for that specific questions (right now it says something about terms and conditions - ignore that I ad just left it like that for now because I was following a tutorial). 总会有4个答案,但我想跟踪以后再检查哪个答案,所以我想给每个答案一个唯一的ID "question" + questionNum + "Answer" + answerNum"question" + questionNum + "Answer" + i所以我做了这个answersGenerator函数,该函数应该为我提供4个独特的答案选择填充,供用户输入特定问题的答案(现在它说了一些有关条款和条件的内容-忽略了我的广告只是这样写了现在,因为我正在关注教程)。 Here is all my code: 这是我所有的代码:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import logo from './logo.svg';
import './App.css';

var questionNum = 1;
var answerNum = 1;

class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      quizTitle: "",
      author: "",
      question: "",
      terms: false,
      test: "",
    };

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    const target = event.target;
    const value = target.type === "checkbox" ? target.checked : target.value;
    const name = target.name;

    this.setState({
      [name]: value
    });
  }

  handleSubmit(event) {
    event.preventDefault();
    console.log(this.state);
  }

  render() {
    return (
      <div className="App">
        <div>
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <h1 className="App-title">Welcome to React</h1>
          </header>
          <p className="App-intro">
            To get started, edit <code>src/App.js</code> and save to reload.
          </p>
        </div>

        <div className="container">
          <div className="columns">
            <div className="formDiv">
              <form className="form" onSubmit={this.handleSubmit}>
                <div className="field">
                  <label className="label">Give your quiz a title.</label>
                  <div className="control">
                    <input
                      className="input"
                      type="text"
                      name="quizTitle"
                      value={this.state.quizTitle}
                      onChange={this.handleChange}
                    />
                  </div>
                </div>

                <div className="field">
                  <label className="label">Who's the Author?</label>
                  <div className="control">
                    <input
                      className="input"
                      type="text"
                      name="author"
                      value={this.state.author}
                      onChange={this.handleChange}
                    />
                  </div>
                </div>

                <div className="questions" id="questions">
                  <div className="question" id={'questionGroup' + questionNum}>
                    <div className="field">
                      <label className="label" id={'question' + questionNum}>Question {questionNum}</label>
                      <div className="control">
                        <input
                          className="input"
                          type="text"
                          name='question'
                          value={this.state.question}
                          onChange={this.handleChange}
                        />
                      </div>
                    </div>

                    <div className="answersDiv">
                    <label className="label">Answers</label>
                      <div className="field">
                        <div className="control">
                          <label className="checkbox">
                              {this.answersGenerator()}
                          </label>
                        </div>
                      </div>
                    </div>

                </div>
              </div>
              <div className="field">
                  <div className="endButtons">
                    <button id="addQuestionButton"
                      onClick={addQuestion}>Add Question</button>
                    <input
                      type="submit"
                      value="Submit"
                      id="submitButton"
                      className="button is-primary"
                    />
                  </div>
              </div>
              </form>
          </div>

            <div className="column is-3">
              <pre>
                <code>
                  <p>Quiz Title: {this.state.quizTitle}</p>
                  <p>Author: {this.state.author}</p>
                  <p>Question: {this.state.question}</p>
                  <p>Terms and Condition: {this.state.terms}</p>
                  <p>Do you test?: {this.state.test}</p>
                </code>
              </pre>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

function answersGenerator () {

  console.log("hello this is answer generator");
  var div = document.createElement('div');
  div.className = 'answers' + {questionNum};

  for (var i = 1; i < 5; i++){

    div.innerHTML = 
      '<div className="field">\
      <div className="control">\
        <label className="checkbox">\
        <label className="label">Answers</label>\
            <input\
              name="terms"\
              type="checkbox"\
              id="question'+{questionNum}+'Answer'+{i}+'"\
              checked={this.state.terms}\
              onChange={this.handleChange}\
            />\
            I agree to the{" "}\
            <a href="https://google.com">terms and conditions</a>\
        </label>\
      </div>';
    document.getElementsByClassName('answersDiv')[0].appendChild(div)
  }
}


function addQuestion () {
  questionNum++;
  console.log(questionNum + "that is the question number");

  var div = document.createElement('div');

    div.className = "questions" + questionNum;

    div.innerHTML =
        '<div id="questionGroup'+{questionNum}+'">\
        Question '+{questionNum}+'<br />\
        <input type="text" name="question'+{questionNum}+'"/><br />\
        Answers<br />\
        Check the box(es) for the correct answer(s).<br />\
        <input type="checkbox" name="question'+{questionNum}+'Answer1Box" />\
        <label for="question'+{questionNum}+'Answer1"><input type="text" name="question'+{questionNum}+'Answer1"/></label><br />\
        <input type="checkbox" name="question'+{questionNum}+'Answer2Box" id= />\
        <label for="question'+{questionNum}+'Answer2"><input type="text" name="question'+{questionNum}+'Answer2"/></label><br />\
        <input type="checkbox" name="question'+{questionNum}+'Answer3Box"  />\
        <label for="question'+{questionNum}+'Answer3"><input type="text" name="question'+{questionNum}+'Answer3"/></label><br />\
        <input type="checkbox" name="question'+{questionNum}+'Answer4Box"  />\
        <label for="question'+{questionNum}+'Answer4"><input type="text" name="question'+{questionNum}+'Answer4"/></label><br />\
        </div>';

      document.getElementsByClassName('questions')[0].appendChild(div)


}


export default App;

There's a few things to just ignore in here, i just wasn't sure how much info you needed. 这里有些事情要忽略,我不确定您需要多少信息。 So the issue is that I get an error when I call my answersGenerator function in my render function. 所以问题是当我在render函数中调用answersGenerator函数时出现错误。 Here's the error Uncaught TypeError: this.answersGenerator is not a function Here's the small piece where that is 这是错误Uncaught TypeError: this.answersGenerator is not a function这是小片段

            <div className="answersDiv">
            <label className="label">Answers</label>
              <div className="field">
                <div className="control">
                  <label className="checkbox">
                      {this.answersGenerator()}
                  </label>
                </div>
              </div>
            </div>

I appreciate the help, if you have any other tips for me other than this issue I am having I am all ears. 感谢您的帮助,如果您有其他建议,而不是其他问题,我将不胜枚举。 I am very new at this, being js and React. 非常新的这个,是js和反应。

UPDATE: I have edited the answersDiv to be just this (I relized it was being called inside a checkbox) 更新:我已经将answersDiv编辑为仅此(我认为它在复选框内被调用)

        <div className="answersDiv">
        <label className="label">Answers</label>

                  {answersGenerator()}

        </div>

I am still getting the same errors though. 我仍然遇到相同的错误。

At first glance it looks like you haven't defined your answersGenerator() function within your App class. 乍一看,您似乎尚未在App类中定义answersGenerator()函数。

Thus, this.answersGenerator() doesn't exist. 因此, this.answersGenerator()不存在。

Try just using answersGenerator() without the this . 尝试只用answersGenerator()没有this

You're receiving the error because the answersGenerator() isn't a method of your class App , so, you can't refer to it using this . 因为answersGenerator()不是类App的方法,所以您收到错误,因此,您不能使用this来引用它。 If you want to do on that way, move you function to inside the component, like this: 如果要这样做,请将函数移至组件内部,如下所示:

class App extends Component {
    // your component definition etc..
    answersGenerator = () => {
        // your function implementation
    }
    // the rest of your component
}

TIP: 小费:

If you dont want to have to always bind the function, like: 如果您不想总是绑定该函数,例如:

this.handleChange = this.handleChange.bind(this);

Declare your method like: 声明您的方法,例如:

handleChange = (event) => { // the implementation }

Instead of 代替

handleChange(event) { // the implementation }

The () => {} , known as arrow function , does the bind for your. () => {} ,称为arrow function ,为您执行绑定。

EDIT 编辑

You're developing with React, that supports creating HTML inside your code. 您正在使用React开发,它支持在代码内部创建HTML So, you can create an array of answers, then, return a div with the answers mapped inside. 因此,您可以创建一个答案数组,然后返回一个内部映射了答案的div The map will take each answer and render inside the div . map将获取每个answer并在div内进行渲染。 Try to define your method as below: 尝试如下定义您的方法:

answersGenerator => () {
    console.log("hello this is answer generator");
    var answers = []
    for (var i = 1; i < 5; i++){
      answers.push(
        <div className="field">
          <div className="control">
            <label className="checkbox">
               <label className="label">Answers</label>
               <input
                 name="terms"
                 type="checkbox"
                 id=`question${questionNum}Answer${i}`
                 checked={this.state.terms} 
                 onChange={this.handleChange}
               />
               I agree to the{" "}
               <a href="https://google.com">terms and conditions</a>
           </label>
         </div>
       );
    } 
    return <div className=`answer${questionNum}`> {answers.map(answer => answer)} </div>
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM