【问题标题】:Rendering a component multiple times with different props in React在 React 中使用不同的 props 多次渲染组件
【发布时间】:2018-01-26 17:49:14
【问题描述】:

我有一个组件要渲染四次,每次都使用不同的道具。为了让我的代码更简洁一点,而不是每次都为组件及其 props 写出 JSX,我尝试使用 map 来创建组件的不同实例。现在,它是这样的:

import React, { Component } from 'react';
import Panel from './components/Panel';
import Results from './components/Results';
import Intro from './components/Intro';

const questionsMap = [0, 1, 2, 3];

class React extends Component {
    constructor (props) {
        super (props);
        this.state = {
            questions: ['question1', 'question2', 'question3', 'question4'],
            answers: ['answers1', 'answers2', 'answers3', 'answers4']
        }
        this.onSelect = this.onSelect.bind(this);
    }

    onSelect(value) {
        /* Some code for when buttons are clicked */
    }

    render () {
        return (
            <Intro />
            {questionsMap.map(i => {
            return <Panel question={this.state.questions.i} answers={this.state.answers.i} onSelect={this.onSelect} />
            })}
            <Results />
        );
    }
}

export default App;

现在我收到一个Unexpected token 错误,指向我的渲染下以{questionsMap.map()} 开头的行,也就是我尝试实际执行我提到的映射的部分。我假设我使用错误的语法来完成我想要的?

【问题讨论】:

  • 因为你不想为你的类命名为 React。使用类 PanelContainer 扩展 React.Component
  • 只返回一个元素。将其包装在 div 或其他东西中。

标签: javascript reactjs


【解决方案1】:

下面是正确的语法:

import React, { Component } from 'react';
import Panel from './components/Panel';
import Results from './components/Results';
import Intro from './components/Intro';

const questionsMap = [0, 1, 2, 3];

class React extends Component {
    constructor (props) {
        super (props);
        this.state = {
            questions: ['question1', 'question2', 'question3', 'question4'],
            answers: ['answers1', 'answers2', 'answers3', 'answers4']
        }
        this.onSelect = this.onSelect.bind(this);
    }

    onSelect(value) {
        /* Some code for when buttons are clicked */
    }

    render () {
        return (
            <div>
              <Intro />
              {questionsMap.map(i => {
              return <Panel question={this.state.questions[i]} answers={this.state.answers[i]} onSelect={this.onSelect} />
            })}
              <Results />
            </div>
        );
    }
}

export default App;

但有些事情并不是一个好的做法,我认为这是某种测试,所以我不希望您将其中一个组件命名为 React

除此之外,您可以简单地映射状态,我将代码更改如下:

import React, { Component } from 'react'; import Panel from './components/Panel'; import Results from './components/Results'; import Intro from './components/Intro';


class React extends Component {
    constructor (props) {
        super (props);
        this.state = {
            questions: ['question1', 'question2', 'question3', 'question4'],
            answers: ['answers1', 'answers2', 'answers3', 'answers4']
        }
        this.onSelect = this.onSelect.bind(this);
    }

    onSelect(value) {
        /* Some code for when buttons are clicked */
    }

    render () {
        return (
            <div>
              <Intro />
              {this.state.questions.map((question, questionIndex) => {
                return (<Panel
                question={question}
                answers={this.state.answers[questionIndex]}
                onSelect={this.onSelect} />
              )
            })}
              <Results />
            </div>
        );
    } }

export default App;

或者,您可以拥有一个对象数组,其中包含一个名为 question 和另一个名为 answer 的字段,只是为了给您另一个想法。

【讨论】:

  • 啊,这是一个很棒的答案,谢谢!作为记录,我没有将我的组件命名为“React”。我快速通过一个示例而不是使用我相当冗长的实际代码,这是一个错字。但无论如何,谢谢!
  • 我觉得不用担心!
  • 将其中一个答案标记为正确,这样人们就不会继续回答;),如果您有任何其他问题或需要我澄清的事情,请告诉我!
  • 我正在尝试将您的问题标记为正确,但 SO 告诉我我的问题发布时间不够长。
  • 如何根据索引访问组件中接收到的props?
【解决方案2】:

一开始,render 只能返回一个元素。你应该用div 包装你的组件。其次,this.state.questions.i 是错误的语法。使用this.state.questions[i]。 最后,我认为有更好的方法:

return (
  <div>
    <Intro />
    {
      this.state.questions.map((question, i) => {
        return <Panel question={question} answers={this.state.answers[i]} onSelect={this.onSelect} />
      })
    }
    <Results />
  </div>
);

【讨论】:

    【解决方案3】:
    1. 不要给你的班级命名React
    2. 除非您使用 React 16,否则您需要将所有内容包装在 div 中(在渲染方法上)
    3. 你不需要 questionsMap 。您可以使用map 免费提供的索引,map 函数的第一个参数是元素,第二个参数是索引。
    4. 在返回之前,在 render 中解构您的问题和答案,如下所示:`const { 问题,答案} = this.state;为了便于阅读。
    5. 祝你好运

    【讨论】:

      【解决方案4】:

      return 方法只需要 1 个孩子,在您的示例中,它有 3 个孩子,即:

      • 介绍组件
      • &lt;Panel&gt;s 的数组
      • 结果组件。

      要解决这个问题,最简单的方法是包含在&lt;div&gt;...&lt;/div&gt; 标签内

      或者如果这个额外的 div 妨碍了样式,您可以简单地包含在 &lt;&gt;...&lt;/&gt; 标签中

      【讨论】:

        【解决方案5】:

        问题是你返回的元素不止一个,如果你想返回多个元素,你可以将它们包装在一个 div 中,这会在 DOM 上产生一个额外的元素,或者你可以使用 React 片段

        案例一:

            render () {
                return (
                    <>        //<React.fragment //either you the empty tag or the one with React.fragment they are both are valid
                        <Intro />
                        {questionsMap.map((_,i) => {
                            return <Panel question={this.state.questions[i]} answers= 
                        {this.state.answers[i]} onSelect={this.onSelect} />})}
                        <Results />
                    </>       //</React.fragment> 
                );
            }
        

        案例2:

            render () {
                return (
                    <div>       
                        <Intro />
                        {questionsMap.map((_,i) => {
                            return <Panel question={this.state.questions[i]} answers= 
                        {this.state.answers[i]} onSelect={this.onSelect} />})}
                        <Results />
                    </div> 
                );
            }
        

        【讨论】:

          【解决方案6】:

          您没有正确使用地图功能。

          请检查以下代码

          import React, { Component } from 'react';
          
          import Panel from './components/Panel';
          import Results from './components/Results';
          import Intro from './components/Intro';
          
          const questionsMap = [0, 1, 2, 3];
          
          class React extends Component {
              constructor (props) {
                  super (props);
                  this.state = {
                      questions: ['question1', 'question2', 'question3', 'question4'],
                      answers: ['answers1', 'answers2', 'answers3', 'answers4']
                  }
                  this.onSelect = this.onSelect.bind(this);
              }
          
              onSelect(value) {
                  /* Some code for when buttons are clicked */
              }
          
              render () {
                  return (
                      <Intro />
                      {questionsMap.map((_,i) => {
                      return <Panel question={this.state.questions[i]} answers={this.state.answers[i]} onSelect={this.onSelect} />
                      })}
                      <Results />
                  );
              }
          }
          
          export default App;
          

          map 中的第一个参数是值,第二个参数是索引。因为,我们不需要地图中的值,所以我将其作为_。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-10-31
            • 1970-01-01
            • 2021-08-28
            • 1970-01-01
            • 1970-01-01
            • 2016-11-18
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多