从地图对象渲染react组件

时间:2019-05-06 15:55:32

标签: javascript reactjs

在reactjs中,我试图从Map对象渲染组件。更具体地说,在按下按钮时,我创建了一个新的“ FormRow”组件,为了方便起见,我将其存储在javascript Map对象中(因为稍后我将要使用它)。每当发生这种情况时,我都希望呈现刚刚添加的新组件,但是我不知道如何从地图中获取它。

我尝试使用以下方法以不同方式解决问题:

  1. myMap.forEach(key => {return myMap.get(key)});
  2. myMap.forEach(component => {return component});
  3. myMap.values()
  4. myMap.entries()
  5. Object.keys(myMap).map(...)

我没有尝试的事情:

  1. https://stackoverflow.com/a/50183395/9282731(我不太清楚...)

这是我的简化的代码:

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()方法向用户呈现其期望的结果。

3 个答案:

答案 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()