我想创建一个react组件实例,并以编程方式将其渲染到静态位置。 我的用例是,我以未知的长度打开一系列对话框,当收到对话框的响应时,我打开下一个。
我想做类似的事情:
const DialogExample = () => ({ question, onAnswer }) =>
(<div>
{question}
<button onClick={onAnswer}>answer</button>
</div>);
class SomeComponent extends React.Component {
async start() {
const questions = await getSomeDynamicQuestions();
this.ask(questions);
}
ask(questions) {
if (questions.length === 0) {
// DONE.. (do something here)
return;
}
const current = questions.pop();
React.magicMethod(
// The component I want to append:
<DialogExample
question={current}
onAnswer={() => this.ask(questions)}
/>,
// Where I want to append it:
document.getElementsByTagName('body')[0]);
}
render() {
return (
<div>
<button onClick={this.start}>start</button>
</div>);
}
}
我知道那不是很“像反应”,而且我想这样做的“正确”方法是将这些问题存储在状态中,并在“ someComponent”(或其他)渲染函数中对其进行迭代,但是,我认为这种模式在我的特定需求中很有意义。
答案 0 :(得分:2)
听起来像Portals的情况。我建议做这样的事情:
class SomeComponent extends React.Component {
constructor(props) {
super(props);
this.body = document.getElementsByTagName('body')[0];
this.state = {
questions: [],
}
}
async start() {
const questions = await getSomeDynamicQuestions();
this.setState({ questions });
}
nextQuestion() {
this.setState(oldState => {
const [first, ...rest] = oldState.questions;
return { questions: rest };
})
}
render() {
const { questions } = this.state;
return (
<div>
<button onClick={this.start}>start</button>
{questions.length > 0 && ReactDOM.createPortal(
<DialogExample
question={questions[0]}
onAnswer={() => this.nextQuestion()}
/>,
this.body,
)}
</div>
);
}
}