【问题标题】:functional component to receive array from parent component and map through it从父组件接收数组并通过它映射的功能组件
【发布时间】:2019-12-11 22:43:31
【问题描述】:

更新:使用来自 u/kinduser 的代码,这就是我所在的位置

import React, { Component } from 'react'
import MultiChoiceQuestions from '../questions/MultiChoice'
import Question from '../questions/Question'

class CNA extends Component {
  constructor(props) {
    super(props)
    this.state = {
      newChoiceArray: [
        { id: 1, text: '1', questionId: 'favourite number?', value: '1' },
        { id: 2, text: '2', questionId: 'favourite number?', value: '2' },
        { id: 3, text: '3', questionId: 'favourite number?', value: '3' },
        { id: 4, text: 'This is a new question', questionId: 'favourite number?', value: '4' },
      ],
      ChoiceArray: [
        { id: 1, text: '1', questionId: 'favourite number?', value: '1' },
        { id: 4, text: 'This is a new question', questionId: 'favourite number?', value: '4' },
      ],
    }
  }

  handleSelected = selected => {
    console.log('Button Selected', selected)
  }

  render() {
    const { newChoiceArray, ChoiceArray } = this.state
    return (
      <div>
        <p>This is the cna survey</p>
        <Question questionText="Hello" />
        <MultiChoiceQuestions handleClick={this.handleSelected} multiChoiceArray={newChoiceArray} />
        <MultiChoiceQuestions handleClick={this.handleSelected} multiChoiceArray={ChoiceArray} />
      </div>
    )
  }
}

export default CNA

子组件

const MultiChoiceQuestions = ({ handleClick, multiChoiceArray }) => {
  const handleClickFn = questionChoice => handleClick(questionChoice)
  {
    console.log('test', multiChoiceArray)
  }
  return (
    <div>
      {multiChoiceArray.map(questionChoice => (
        <MultiChoiceQuestions
          key={questionChoice.id}
          onClick={handleClickFn(questionChoice)}
          choice={questionChoice.text}
        />
      ))}
    </div>
  )
}

Console output: `test (4) [{…}, {…}, {…}, {…}]0: {id: 1, text: "1", questionId: "favourite number?", value: "1"}1: {id: 2, text: "2", questionId: "favourite number?", value: "2"}2: {id: 3, text: "3", questionId: "favourite number?", value: "3"}3: {id: 4, text: "This is a new question", questionId: "favourite number?", value: "4"}length: 4__proto__: Array(0)
CNA.js:23 Button Selected {id: 1, text: "1", questionId: "favourite number?", value: "1"}
CNA.js:23 Button Selected {id: 2, text: "2", questionId: "favourite number?", value: "2"}
CNA.js:23 Button Selected {id: 3, text: "3", questionId: "favourite number?", value: "3"}
CNA.js:23 Button Selected {id: 4, text: "This is a new question", questionId: "favourite number?", value: "4"}
MultiChoice.js:23 test undefined
MultiChoice.js:23 test undefined`

所以看起来像定义了来自父组件的数组,由于某种原因选择了按钮,然后数组变得未定义

这可能吗?我的父组件有一个对象数组,我的子组件根据该数组内的对象数量呈现按钮。

所以基本上我不希望我的父组件映射和渲染按钮,我想将我的数组作为道具传递,然后子组件将渲染按钮(n=数组中的对象)

Sandbox Link

伪子组件看起来像这样

 <MultiChoiceQuestion
            key={questionChoice.id}
            handleClick={() => this.handleSelected(questionChoice)}
            onClick={this.handleSelected}
            questions={multiChoiceArray} // will receive array as props
            choice={questionChoice.text}
  />

这就是所有事物在瞬间的结构

const MultiChoiceQuestion = props => {
  const { handleClick, choice } = props
  return (
    <div>
     // I want my array.map to live somwhere in this component
      <button onClick={handleClick} type="button">
        {choice}
      </button>
    </div>
  )

父组件

import React, { Component } from 'react'
import MultiChoiceQuestion from '../questions/MultiChoice'
import Question from '../questions/Question'

class CNA extends Component {
  constructor(props) {
    super(props)
    this.state = {
      multiChoiceArray: [
        { id: 1, text: '1', questionId: 'favourite number?', value: '1' },
        { id: 2, text: '2', questionId: 'favourite number?', value: '2' },
        { id: 3, text: '3', questionId: 'favourite number?', value: '3' },
        { id: 4, text: 'This is a new question', questionId: 'favourite number?', value: '4' },
      ],
    }
    this.handleSelected = this.handleSelected.bind(this)
  }

  handleSelected = selected => {
    console.log('Button Selected', selected)
  }

  render() {
    const { multiChoiceArray } = this.state
    return (
      <div>
        <p>This is the cna survey</p>
        <Question questionText="Hello" />
        {multiChoiceArray.map(questionChoice => ( // Don't want this map function here
          <MultiChoiceQuestion
            key={questionChoice.id}
            handleClick={() => this.handleSelected(questionChoice)}
            onClick={this.handleSelected}
            choice={questionChoice.text}
          />
        ))}
      </div>
    )
  }
}

export default CNA

【问题讨论】:

    标签: javascript reactjs oop ecmascript-6


    【解决方案1】:

    当然有可能 - 只需将 map 逻辑移动到您的子组件中即可。

    const MultiChoiceQuestions = ({ handleClick, multiChoiceArray }) => {
      const handleClickFn = (questionChoice) => handleClick(questionChoice);
    
      return (
        <div>
           {multiChoiceArray.map(questionChoice => (
             <MultiChoiceQuestion
               key={questionChoice.id}
               handleClick={handleClickFn(questionChoice)}
               onClick={this.handleSelected}
               choice={questionChoice.text}
             />
           ))}
        </div>
    );
    

    在你的父母内部:

    <MultiChoiceQuestions 
        handleClick={this.handleSelected} 
        multiChoiceArray={this.state.multiChoiceArray} />
    

    【讨论】:

    • 组件名称应该是 MultiChoiceQuestions :)
    • 嗯,我不认为这是我所追求的,如果我的父组件中有多个 MultiChoiceQuestion 组件,我希望能够提供不同的数组。数组参数将是一个道具
    • @invrt 好吧,使用这样的解决方案,您实际上可以提供不同的数组
    • 那我一定是做错了什么,我收到“TypeError: Cannot read property 'map' of undefined”在 multiChoice 组件上未定义。请问您的答案可以多解释一下吗?
    • @invrt 更新答案:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-14
    • 2020-05-12
    • 2018-09-04
    • 2021-03-14
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    相关资源
    最近更新 更多