我有一个名为: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>
谁是“替代”父母?问题(因为它是嵌套的)还是QuestionList(因为它是创建的)?
如何将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;
答案 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 API和cloneElement()。
查看示例:
答案 1 :(得分:0)
处理程序旨在在上下文中工作……在状态……中然后在<QuestionList/>
中对状态进行管理。准备特定的参数化处理程序,并使用它们来更新公共状态。
束缚“所需的”(更细粒度或更具体的)处理程序以通过结构传递值是不切实际的。效率也不高。
看看“ Formik”项目中的数据/状态流-表单,验证和字段。它可能是解决此问题的很好的灵感来源。
<Question/>
和<Alternative/>
应该是无状态的功能组件-您不需要它们是有状态的。吻,亚尼...