简体   繁体   English

React中的动态需求

[英]Dynamic requires in React

Edit: I created wrappers for each different component, required the necessary collections and passed them as props to a main, generic component. 编辑:我为每个不同的组件创建了包装器,需要必需的集合,并将它们作为道具传递给主要的通用组件。

We made 3 very similar components using React, and ended up having three really similar files with some minor modifications, depending on the specific component. 我们使用React制作了3个非常相似的组件,最终得到了3个非常相似的文件,并进行了一些细微的修改,具体取决于特定的组件。
My question is really simple (but might be hard to implement), we want to utilize the same file for that base, so i want to dynamically use requires, and initialize variables, how can i do it? 我的问题确实很简单(但可能很难实现),我们想为该基础利用相同的文件,所以我想动态地使用require并初始化变量,我该怎么做?

var ProtocolSelectedCollection = require("../collections/ProtocolSelectedCollection");
var selectedCollection = new ProtocolSelectedCollection();
var baseURL = Utils.getSystemUrl();

easyGrid({
    gridName: "protocolSelectedCollection"
});

In the code above, for example, i would like to require a different file from /collections/ , depending on the component, and i would also like to name the gridName differently. 例如,在上面的代码中,根据组件,我想需要一个不同于/ collections /的文件,并且我也想对gridName进行不同的命名。
So, how can i do it? 那么,我该怎么办呢? I will post more code if necessary or clear any doubts about it. 如有必要,我将发布更多代码或清除对此的任何疑问。
So here is the full component, it's really small. 这是完整的组件,非常小。

var React = require('react');

const Utils = require("Utils");

var RowCt = require("reactor/src/FlexGrid/components/Layout/Row/Row");
var Col = require("reactor/src/FlexGrid/components/Layout/Col.jsx");
var Row = require("reactor/src/FlexGrid/components/Layout/Row/RowPresentation.jsx");
var Box = require("reactor/src/FlexGrid/components/Layout/Box.jsx");
var ContentLabel = require("reactor/src/Atomic/components/Mols/ContentLabel.jsx");
var AsyncLoading = require("reactor/src/Atomic/components/Helpers/AsyncLoading/AsyncLoading");
var Store = require("reactor/src/store/store");
var Provider = require("react-redux").Provider;
var FormControl = require('reactor/src/Form/components/Atoms/FormControl/FormControl');
var FormGroup = require("reactor/src/Form/components/Mols/FormGroup");
var InputAddon = require("reactor/src/Form/components/Atoms/InputAddon");
var InputGroup = require("reactor/src/Form/components/Mols/InputGroup/InputGroup.jsx");
var easyGrid = require("reactor/src/FlexGrid/components/Helpers/EasyGrid");
var when = require("when");

var ProtocolSelectedCollection = require("../collections/ProtocolSelectedCollection");
var selectedCollection = new ProtocolSelectedCollection();
var baseURL = Utils.getSystemUrl();

easyGrid({
    gridName: "protocolSelectedCollection"
});

var cursorPointer = {
    cursor: 'pointer'
};

var rowWrapper = {
    borderWidth: '0px 0px 1px',
    borderStyle: 'solid',
    borderColor: 'rgb(204, 204, 204)',
    marginBottom: '10px',
    cursor: 'pointer'
};


require("./ProtocolAuthorizedWidget.css");
require("reactorCmps/tokens/general");

module.exports = React.createClass({
    componentDidMount() {
        var me = this;

        return me.loadData();
    },

    filterValue: "",

    loadData() {
        var me = this;

        return me.refs.async.getWrappedInstance().loadData(true);
    },

    getChildren(data) {
        var me = this, protocolsData = Array.isArray(data) ? data : [], protocols = [];

        if (!protocolsData.length) {
            return (
                <span>{SE.t(103092)}</span>
            );
        }

        protocolsData.map(function(element, i) {
            protocols.push(
                <div style={rowWrapper}
                    key={i}
                    onMouseLeave={me.setRowState.bind(me, element.cdproctype, 'leave')}
                    onMouseOver={me.setRowState.bind(me, element.cdproctype, 'over')}
                    onClick={me.startProtocol.bind(me, element.cdproctype)}
                    title={SE.t(104859)}>

                    <RowCt
                        oid={element.cdproctype}
                        selectType={0}
                        multireducerKey={"protocolSelectedCollection"}>

                        <Col xs sm md lg>
                            <Row nested>
                                <Col xs={1} sm={1} md={1} lg={1} >
                                    <div ref={"protocol" + element.cdproctype}></div>
                                    <img ref={"protocolImage" + element.cdproctype} 
                                        src={baseURL + "/common/images/type_icons/64x64/" + element.fgicon + ".png"} 
                                        className="rowImage" />
                                </Col>
                                <Col xs={11} sm={11} md={11} lg={11}>
                                    <Box>
                                        <ContentLabel title={element.idproctype} text={element.nmtitle}></ContentLabel>
                                    </Box>
                                </Col>
                            </Row>
                        </Col>
                    </RowCt>
                </div>

            );
        });

        return (
            <div>
                <div>
                    {protocols}
                </div>
            </div>
        );
    },

    startProtocol(cdproctype) {
        var url = baseURL + "/document/dc_protocol/protocol_data.php?caption=&action=1&cdproctype=" + cdproctype;
        var width = 700;
        var height = 515;

        Utils.openPopUp(url, width, height); 
    },

    setRowState(cdproctype, event) {
        var me = this;

        if (event === 'over') {
            $(me.refs.async.getWrappedInstance().refs['protocolImage' + cdproctype]).hide();
            $(me.refs.async.getWrappedInstance().refs['protocol' + cdproctype]).addClass("se-valign btn btn-success seicon-play playButton rowImage");
        } else if (event === 'leave') {
            $(me.refs.async.getWrappedInstance().refs['protocolImage' + cdproctype]).show();
            $(me.refs.async.getWrappedInstance().refs['protocol' + cdproctype]).removeClass();
        } 
    },

    filterProtocol(e) {
        var me = this;
        var enterKeyCode = 13;

        if (e.target) {
            me.filterValue = e.target.value;
        }

        if (e.nativeEvent.keyCode === enterKeyCode) {
            me.loadData();
        }
    },

    getData() {
        var me = this, deferred = when.defer();
        var oid = me.props.CardOid;
        var searchTerm = me.filterValue;

        selectedCollection.fetch({oid: oid, searchTerm: searchTerm}).then(function(results) {
            deferred.resolve(results);
        });

        return deferred.promise;
    },

    render() {
        var me = this, searchFilter;

        searchFilter = (
            <div>
                <div>
                    <FormGroup>
                        <InputGroup>
                            <InputAddon 
                                onClick={me.loadData}
                                style={cursorPointer}
                                className="seicon-search"
                                title={SE.t(214653)}
                                >

                            </InputAddon>
                            <div>
                                <FormControl
                                    onKeyPress={me.filterProtocol}
                                />
                            </div>
                        </InputGroup>
                    </FormGroup>
                </div>
            </div>
        );

        return (
            <div>
                <div>
                    {searchFilter}
                </div>

                <Provider store={Store} withRef>
                    <AsyncLoading
                        ref="async"
                        oid={"protocolSelectedCollection" + me.props.CardOid}
                        fireLoad
                        loadFn={me.getData}
                        getChildren={me.getChildren}
                    />
                </Provider>

            </div>
        );
    }

});

If your components are really similar,you can create one single component which does some actions and renders some result based on props. 如果您的组件确实很相似,则可以创建one single component ,该one single component根据道具进行一些操作并呈现一些结果。

Just pass some props. 只要传递一些道具。 And inside of your component, do your actions like you do in those 3 component separately. 在组件内部,像在这三个组件中一样分别执行操作。 Here, i tried to demonstrate how to use props to render different results from same component: 在这里,我试图演示如何使用道具从同一组件渲染不同的结果:

class MixedComponent extends React.Component {
  constructor(props) { 
    super(props)
    this.state = {type: ''}
  }

  componentDidMount() {
    if (this.props.prop1) // if prop1 exists
      this.setState({type: 'do something'})
    else 
      this.setState({type: 'Something else'})
  }

  render() {
    let result;
    if (this.props.prop1) {
      result = (
        <div>
          Render this component based on <strong>{this.props.prop1}</strong>
          <p>Type -> {this.state.type}</p>
        </div>
      )
    } else if (this.props.prop2) {
      result = (
        <div>
          Render this component based on <strong>{this.props.prop2}</strong>
          <p>Type -> {this.state.type}</p>
        </div>
      )
    }
    else if (this.props.prop3) {
      result = (
        <div>
          Render this component based on <strong>{this.props.prop3}</strong>
          <p>Type -> {this.state.type}</p>
        </div>
      )
    }
    return result
  }
}

And use this component with different props in your main component: 并将此组件与主要组件中的其他道具一起使用:

class Main extends React.Component {
  render() {
    return (
      <div>
        <h4>Render different results based on props with same component!</h4>
        <hr/>
        <MixedComponent prop1="Hello,"/>
        <MixedComponent prop2="Dear"/>
        <MixedComponent prop3="World!"/>
      </div>
     )
  }
}

This is just a demonstration of using props. 这只是使用道具的演示。 You can derive the idea from here. 您可以从这里得出想法。 Here is a working example on codepen : 这是有关codepen的工作示例:

https://codepen.io/anon/pen/dREqZK?editors=1010 https://codepen.io/anon/pen/dREqZK?editors=1010

You can play with it. 你可以玩。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM