在reactjs中,我试图从Map对象渲染组件。更具体地说,在按下按钮时,我创建了一个新的“ FormRow”组件,为了方便起见,我将其存储在javascript Map对象中(因为稍后我将要使用它)。每当发生这种情况时,我都希望呈现刚刚添加的新组件,但是我不知道如何从地图中获取它。
我尝试使用以下方法以不同方式解决问题:
我没有尝试的事情:
这是我的简化的代码:
FormComposer.js:
constructor() {
super();
this.state = {
counter: 0,
myMap: new myMap()
};
this.handleCreateNewRow = this.handleCreateNewRow.bind(this);
}
/** It returns a new FormRow. */
handleCreateNewRow() {
let cloneState = this.state;
let newRow = (
<FormRow // <-- the component that I want to render.
key={this.state.counter}
rowNumber={this.state.counter}
/>
);
cloneState.myMap.set(cloneState.counter, newRow);
cloneState.counter++; // increment the counter for rows
this.setState(cloneState);
}
render() {
return (
<div className="container-fluid m-3">
<div className="col col-9 float-left">
<div className="row">
<div className="text-left">
<h1>Form Builder</h1>
</div>
</div>
{/* Here is the problem! It automaticly loads all the row created previously */}
{this.state.myMap.forEach(value => {
console.log(value); // check
// it print me what I want, but it doesn't render it...
return value;
})}
</div>
</div>
);
}
console.log(value)
返回:
{$$typeof: Symbol(react.element), type: ƒ, key: "0", ref: null, props: {…}, …}
这是我期望的输出,但是我不知道为什么render()方法不呈现它。如果使用Array更改Map对象,则此示例有效,并且render()方法向用户呈现其期望的结果。
答案 0 :(得分:3)
当您使用序号作为键时,我看不出有任何理由使用Map
,只是一个数组会更有意义。
但是要从Map
获取所有值,请使用其values
方法:
{this.state.myMap.values()}
您的forEach
无法正常工作,因为forEach
始终返回undefined
,并且对其回调的返回值不做任何事情。
答案 1 :(得分:1)
我对Maps不太了解,但是从另一个角度来看,我会采用更具声明性的方法,因此,请在
中说
handleCreateNewRow()
我会做的
this.setState({ counter: this.state.counter++, anotherMeta.. })
然后渲染
var rows = [];
for (let i = 0; i < counter; i++) {
rows.push(<FormRow key={i} />);
}
return rows;
答案 2 :(得分:1)
在forEach()
上使用undefined
代替返回map()
的{{1}}(这是Map的值散布到一个新数组中):
[...myMap.values()]
这将返回myMap中条目的值。 或者,由于不需要修改值,因此简称为:
{[...this.state.myMap.values()].map(value => {
return value;
})}
另外,请注意,{this.state.myMap.values()}
实际上并没有克隆状态,而是创建了对同一对象的引用。因此,您可以将let cloneState = this.state
重写为:
handleCreateNewRow()