在ReactJS中了解嵌套与父级

时间:2019-05-20 20:39:24

标签: javascript reactjs

我有一个名为:QuestionList的类,它创建Questions子级以及(嵌套的)替代项:

QuestionList渲染:

<Question wording="wording...">
  <Alternative letter="a" text="bla ..." />
  <Alternative letter="b" text="ble ..." />
  <Alternative letter="c" text="bli ..." />
  <Alternative letter="d" text="blo ..." />
</Question>
  1. 谁是“替代”父母?问题(因为它是嵌套的)还是QuestionList(因为它是创建的)?

  2. 如何将Question事件处理程序传递给Alternative?

如果我使用

<Alternative onClick={this.handleClick} (...) /> 

它将通过QuestionList的处理程序(而不是Question的处理程序-所需的行为)。

问题列表

import React, { Component } from 'react';
import InfiniteScroll from 'react-infinite-scroller';
import Loader from 'react-loaders';
import Question from './Question';
import Alternative from './Alternative';

export default class QuestionList extends Component {
constructor(props) {
    super(props);

    this.state = {
        questions: []
    };
}

loadItems(page) {
    let questions = this.state.questions;

    axios.get('https://jsonplaceholder.typicode.com/photos?_start='+ page * 5 +'&_limit=5')
        .then(response => {
            console.log(response.data);
            response.data.map(p => {
                questions.push(p);
            });

            this.setState({questions});
        });
}

handleClick() {
    alert("QuestionList");
}

render() {
    let items = [];
    const loader = <Loader type="ball-scale-multiple" />;

    this.state.questions.map((p, i) => {
        items.push(
            <Question
                title={p.title}
                key={i}
                id={p.id}
            >
                <Alternative onClick={this.props.handleClick} key={1} text={ p.title } letter="a" />
                <Alternative onClick={this.props.handleClick} key={2} text={ p.title } letter="b" />
                <Alternative onClick={this.props.handleClick} key={3} text={ p.title } letter="c" />
                <Alternative onClick={this.props.handleClick} key={4} text={ p.title } letter="d" />
                <Alternative onClick={this.props.handleClick} key={5} text={ p.title } letter="e" />
            </Question>
        )
    });

    return (
        <InfiniteScroll
            key={1}
            pageStart={0}
            loadMore={this.loadItems.bind(this)}
            hasMore={true}
            loader={loader}
        >

            <div className="justify-content-center" id="react-app-questions-list">
                {items}
            </div>
        </InfiniteScroll>
    );
}
}

问题

import React, { Component } from 'react';

export default class Question extends Component {
constructor(props) {
    super(props);

    this.state = {
        answer_class: "unanswered"
    };
}

handleClick(isCorrect, e) {
    // alert(this.props.id + ": " + isCorrect);
    alert("Question");
}

render() {
    return (
        <div className={"list-group list-group-bordered mb-3 " + this.state.answer_class}>
            <div className="list-group-item">
                <div className="list-group-item-body">
                    <h4 className="list-group-item-title">
                        { this.props.title }
                    </h4>
                </div>
            </div>
            { this.props.children }
        </div>
    );
}
}

替代

import React, { Component } from 'react';

class Alternative extends Component {
render() {
    return (
        <a className="list-group-item list-group-item-action react-app-alternative">
            <div className="list-group-item-figure">
                <div className="tile tile-circle bg-primary">{ this.props.letter }</div>
            </div>
            <div className="list-group-item-body"> { this.props.text }</div>
        </a>
    );
}
}

export default Alternative;

2 个答案:

答案 0 :(得分:0)

  

Alternatives的父母是谁? Question(因为它是嵌套的)还是QuestionList(因为它是创建的)?

Alternative的父母是Question。如果您检查Question.props.children数组(请记住Question只是一个对象),您将在此处看到Alternative类型。

function Question({ children }) {
  console.log(children); // children[0].type === Alternative
  return children;
}

详细了解将React元素作为对象here


  

如何将Question事件处理程序传递给Alternative?

您可以注入道具给Question儿童,例如:

function Question({ children }) {
  console.log(children);
  const injectChildren = React.Children.map(children, child =>
    React.cloneElement(child, { letter: `${child.props.letter}-injected` })
  );
  return injectChildren;
}

为此,您需要阅读React Top-Level API并参考React.Children APIcloneElement()

查看示例:

Edit gracious-stallman-0jho6

答案 1 :(得分:0)

处理程序旨在在上下文中工作……在状态……中然后在<QuestionList/>中对状态进行管理。准备特定的参数化处理程序,并使用它们来更新公共状态。

束缚“所需的”(更细粒度或更具体的)处理程序以通过结构传递值是不切实际的。效率也不高。

看看“ Formik”项目中的数据/状态流-表单,验证和字段。它可能是解决此问题的很好的灵感来源。


<Question/><Alternative/>应该是无状态的功能组件-您不需要它们是有状态的。吻,亚尼...