动态 react-bootstrap 轮播分开。 (必须返回一个有效的 React 元素(或 null)。)

Dynamic react-bootstrap carousel breaking apart. (A valid React element (or null) must be returned.)

我会尽力解释。 我想动态创建一个 Carousel。 这是实现这一目标的我的数据的表示。

下面是一个question array。这由一个问题表示(在本例中)有四个答案可供选择 question_list_items.

    let question = [{ id: 52, question: "I still enjoy the things I used to", type: "Text list",
        question_list_items: Array(4)
        0: {id: 164, list_item: "Definitely as much", item_value: "0", sort_order: 4, question_id: 52, …}
        1: {id: 165, list_item: "Not quite so much", item_value: "1", sort_order: 3, question_id: 52, …}
        2: {id: 166, list_item: "Only a little", item_value: "2", sort_order: 2, question_id: 52, …}
        3: {id: 167, list_item: "Not at all", item_value: "3", sort_order: 1, question_id: 52, …}
    ];

主渲染 这是 Carousel 组件的开始。我从 header 部分开始,调用 <Questionnaire/> 组件来填充 body。

return (
    <Carousel
        activeIndex={index}
        direction={direction}
        onSelect={(i,e)=>this.handleSelect(i,e)}
    >

       <Questionnaire/>

    </Carousel>
);

问卷组件
这是我认为出错的地方。 这里我循环遍历this.props.questions里面的所有问题。 我检查问题的 Type 以呈现正确类型的问题。 这是在 switch 的帮助下完成的。在这种情况下,我只显示 <TextList /> 组件。

const Questionnaire = SortableContainer(({items}) => {
    this.props.questions.map((row, index) => {
        let element;
        switch (row.type) {
            case "Text list":
                element = <TextList key={`questionList-${index}`} index={index} row={row} />;
                break;
        }
        return element;
    })
});

TextList 组件

在这个组件中,我构建了一张轮播幻灯片。 该组件调用 <TextListButton /> 组件来呈现当前问题的答案选项。

const TextList = SortableElement(({row}) => {
    console.log("row",row);
    return (
    // ******************************************************************************************************
    // ************************************      LIST TYPE QUESTION     *************************************
    // ******************************************************************************************************
        <Carousel.Item  style={{"padding": "0 20px 0 20px", height: "600px", width: "1024px", textAlign: "center"}}>
            <h3>{row.question}</h3>
            <div style={{ paddingTop: "40px" }}>
                <Row>
                    <Col xs={3} />
                    <Col xs={6}>
                        <div>
                            <ButtonGroup vertical block>
                                {row.question_list_items.map((row, idx) => {
                                    return <TextListButton key={`buttonList-${idx}`} index={idx} row={row} />;
                                })}
                            </ButtonGroup>
                        </div>
                    </Col>
                    <Col xs={3} />
                </Row>
            </div>

            <Carousel.Caption>
                <p>Nulla vitae elit libero, a pharetra augue mollis interdum.</p>
            </Carousel.Caption>
        </Carousel.Item>
    );
});

TextListButton 组件 这将创建每个可供选择的答案项。

const TextListButton = SortableElement(({row}) => {
    console.log("item row",row);
    return (
        <Button>{row.list_item}</Button>
    );
});

关于问卷组件的注意事项

我试图将 Questionnaire 组件包装在 <div> 标签中。这使它呈现,但它不再是轮播,它只是一长串问题和答案。我不确定如何处理这个问题。任何帮助将不胜感激。

const Questionnaire = SortableContainer(({items}) => {
    return (
        <div>  <=********************************************HERE
        {this.props.questions.map((row, index) => {
            let element;
            switch (row.type) {
                case "Text list":
                    element = <TextList key={`questionList-${index}`} index={index} row={row} />;
                    break;

            }
            return element;
        })}
        </div>  <=********************************************HERE
    );
});

声明更新 let element = null;

好像运行答了14题,然后就失败了。 (只有14题)

STACT 追踪

当您定义 let element; 时,它在 Javascript 中初始化为 undefined 并且 如果您的开关与定义的大小写不匹配(在您的示例中 Text list),那么您将返回 undefined,因此返回错误。

旁注,因为你只有一个条件,你不需要 switch/case 你最好使用 if 语句,除非所讨论的示例被精简版本。

由于您使用的是 React 15.x,因此您不能留下孤儿,因此您需要将数组包装在 div 或其他一些 html 元素中:

您的第一个问题是您在不允许的数组中呈现未定义,因此您可以定义 element = null

const Questionnaire = SortableContainer(({items}) => {
    return (
        <div>  <=******************************************** You can remove this if you want or replace it with empty <> fragment
        {this.props.questions.map((row, index) => {
            let element = null; <=********************************************HERE
            switch (row.type) {
                case "Text list":
                    element = <TextList key={`questionList-${index}`} index={index} row={row} />;
                    break;

            }
            return element;
        })}
        </div>
    );
});

你的第二个问题是渲染数组列表而不用 HTML 元素包装。您将不得不重组代码,使其不返回没有父容器的数组子元素。

一种可能的方法是您可以尝试直接更新轮播,如下所示:

<Carousel
activeIndex={index}
direction={direction}
onSelect={(i,e)=>this.handleSelect(i,e)}
>
  {this.props.questions.filter(question => question.type === "Text list")
    .map((row, index) => 
    <Carousel.Item>
      <Questionnaire question={row.question} answers={row.question_list_items} />
    </Carousel.Item>
    )
  }
</Carousel>

并且问卷可以充当仅呈现 question/answers

的哑组件