React将Component添加为变量

时间:2018-03-13 16:35:27

标签: javascript html reactjs

我有一个简单的问题需要解决。我使用npx create-react-app创建了一个反应应用。我创建了一个Map组件,我将其添加到我的视图中:

class App extends Component {
    render() {
        return (
            <div className="App">
                <header className="App-header">
                    <img src={logo} className="App-logo" alt="logo" />
                    <h1 className="App-title">Welcome to React</h1>
                </header>
                <p className="App-intro">
                    To get started, edit <code>src/App.js</code> and save to reload.
                </p>
                <p>
                    <Map />
                </p>
            </div>
        );
    }
}

出现Map组件。现在我想要一个按钮,其中onClick方法调用Map.addImage。首先,它不能是静态的(addImage使用Map成员,这些成员必须在构造函数中初始化)。问题是我知道我必须做var map = new Map()。然后<button type="button" onClick={map.addImage} />但是如何让我的地图出现?我不能去:

<p>
    <map />
</p>

所以问题是我如何才能在屏幕上显示map var map = new Map() render()方法之后,返回上方?

@Edit

Map实施:

export default class Map extends React.Component {

    constructor(props) {
        super(props);
        this.stage = null;
        this.layer = null;
    }
    componentDidMount() {
        //const tween = null;

        this.stage = new Konva.Stage({
            container: this.containerRef,
            width: 1024,
            height: 600
        });


        this.layer = new Konva.Layer();
        //const dragLayer = new Konva.Layer();

        this.stage.add(this.layer);

        /*stage.on("dragstart", function (evt) {
            const shape = evt.target;
            // moving to another layer will improve dragging performance
            shape.moveTo(dragLayer);
            stage.draw();

            if (tween) {
                tween.pause();
            }
            shape.setAttrs({
                shadowOffset: {
                    x: 15,
                    y: 15
                },
                scale: {
                    x: shape.getAttr("startScale") * 1.2,
                    y: shape.getAttr("startScale") * 1.2
                }
            });
        });

        stage.on("dragend", function (evt) {
            const shape = evt.target;
            shape.moveTo(layer);
            stage.draw();
            shape.to({
                duration: 0.5,
                easing: Konva.Easings.ElasticEaseOut,
                scaleX: shape.getAttr("startScale"),
                scaleY: shape.getAttr("startScale"),
                shadowOffsetX: 5,
                shadowOffsetY: 5
            });
        });*/
    }

    render() {
        return (
            <div
                className="container"
                ref={ref => {
                    console.log(ref);
                    this.containerRef = ref;
                }}
            />
        );
    }

    addImage() {
        var imageObj = new Image();
        imageObj.src = './box.png';
        imageObj.misc = { stage: this.stage, layer: this.layer };
        console.log(this.stage)
        imageObj.onload = function () {
            var image = new Konva.Image({
                x: Math.random() * this.misc.stage.getWidth(),
                y: Math.random() * this.misc.stage.getHeight(),
                width: 100,
                height: 100,
                image: imageObj,
                draggable: true
            });
            this.misc.layer.add(image);
            this.misc.layer.draw();
        };
    }
}

1 个答案:

答案 0 :(得分:0)

正如Oblosys所说,你通常不想在React中尝试这样做。如果必须,请使用ref路线。这是有原因的。

但我建议考虑将图像提升到App状态并将其作为道具传递下去。由于您没有为Map组件提供实现,但很难说这会是什么样子,但它看起来像这样的东西

class App extends Component {
  constructor() {
    super();
    this.state = { images: [] };
    this.addImage = this.addImage.bind(this);
  }

  addImage() {
    const newImage = 5; // I obviously have no idea what this actually looks like
    this.setState(({ images }) => ({ images: [...images, newImage] }));
  }

  render() {
    return (
      <div className="App">
         <header className="App-header">
           <img src={logo} className="App-logo" alt="logo" />
           <h1 className="App-title">Welcome to React</h1>
         </header>
         <p className="App-intro">
           To get started, edit <code>src/App.js</code> and save to reload.
         </p>
         <p>
           <Map images={this.state.images} />
         </p>
         <button onClick={this.addImage}>Add an image</button>
       </div>
     );
  }
}

这在所有情况下都不会有效(例如,如果您在Map中使用第三方工具),但这更像是React Way。