我有一个非常具体的例子,我的react组件只呈现代码返回的一部分内容。
大意:
我有一个多维数组:
Rows and Columns[][],其大小未指定,从1个预定义元素开始。
每一列包含另一组组件的一个对象,这些组件应该根据组件的类型有条件地/不同地绘制。
为了能够更容易地阅读代码,我将array.map()
调用拆分为单独的函数。
最后,在我的组件函数的return
中(在这里使用功能组件),我只调用一个函数,它递归地生成要立即填充的JSX代码。
我确实发现这个问题似乎真的很像我想做什么。
在我的代码中,我基本上做了同样的事情,但是React似乎没有正确渲染元素。
问题:
React一次从React.CreateElement()
取回多个元素。
最后,代码应该有多个元素的嵌套呈现。
但是只有第一个Row
被渲染并且正确地出现在DOM中。
相应的Column
应该是嵌套的,根本不出现在DOM中。
从进一步的测试中,我可以说组件函数Column
和以下元素永远不会执行。
从JSX和CreateElement返回的JS-Object是正确的:
它应该在其属性中包含子元素。只是从未执行,从而补充道。
What I tried:
我尝试了多种方法。
我从
const mapRows = () => {
return testvar.map((row, rowIndex) => {
return <Row key={"Row" + rowIndex}>{mapColumns(row, rowIndex)}</Row>;
});
};
// mapColumns
const mapColumns = (row, rowIndex) => {
return row.map((column, columnIndex) => {
return (
<Column key={"Column" + columnIndex}>
<DisplayedElement />
</Column>
);
});
};
通过了直接的React.CreateElement
方法,
到现在:
const mapRows = () => {
return testvar.map((row, rowIndex) => {
return <Row key={"Row" + rowIndex} children={mapColumns(row, rowIndex)}/>;
});
};
const mapCol = () => {
return (<Stuff/>)
}
最后他们两个都没有成功。
问题的例子可以在这里找到:
沙箱示例链接
只是一个快速提醒,我不是一个专业的程序员在这一点上,所以我的代码可能看起来在一个奇怪的风格或可能包含不必要的元素。
,
谢谢!
15.07 Edit1。:将JSFiddle更改为Code Sandbox以显示问题。明确的示例代码块更有说服力
这里需要的是预定义的名为children
的道具。
当你像下面这样包装你的元素时,
<Row key={"Row" + rowIndex}>{mapColumns(row, rowIndex)}</Row>
则您的Row
组件获得一个prop,其中包含名为children
的prop中的所有子元素。使用它来像下面这样渲染它们。
const Row = ({ children }) => {
return (
<div className="row" style={{ display: "flex", flexDirection: "row" }}>
{children}
</div>
);
};
对Column
做同样的操作。
演示工作
const WorkingArea = () => {
// this is the same as in my project
let testvar = [
[{ elementtype: "element A" }, { elementtype: "element B" }],
[{ elementtype: "element C" }, { elementtype: "element D" }]
];
const mapRows = () => {
return testvar.map((row, rowIndex) => {
return <Row key={"Row" + rowIndex}>{mapColumns(row, rowIndex)}</Row>;
});
};
// mapColumns
const mapColumns = (row, rowIndex) => {
return row.map((column, columnIndex) => {
return (
<Column key={"Column" + columnIndex}>
<DisplayedElement type={column.elementtype} />
</Column>
);
});
};
return (
<div className="builder px-2">
<h3>Formular</h3>
<form className="mainForm">
<div className="dropArea border rounded p-3">{mapRows()}</div>
<button
type="submit"
className="btn btn-primary mt-1"
onClick={(e) => {
e.preventDefault();
}}
>
Submit
</button>
</form>
</div>
);
};
// Other Smaller Components, now in the same file for easier fiddle.
const Row = ({ children }) => {
return (
<div className="row" style={{ display: "flex", flexDirection: "row" }}>
{children}
</div>
);
};
const Column = ({ children }) => {
// Contains a lot of other react-dnd functions, probably not necessary thus skipped
return (
<div className="col" style={{ padding: "10px" }}>
{children}
</div>
);
};
const DisplayedElement = ({ type }) => {
return <div>{type}</div>;
};
ReactDOM.render(<WorkingArea />, document.querySelector('.react'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div class='react'></div>