在React中需要动态

时间:2017-07-18 12:27:02

标签: javascript reactjs

编辑:我为每个不同的组件创建了包装器,需要必要的集合并将它们作为道具传递给主要的通用组件。

我们使用React制作了3个非常相似的组件,最终得到了三个非常相似的文件,并进行了一些小的修改,具体取决于具体的组件。
我的问题非常简单(但可能难以实现),我们希望为该基础使用相同的文件,所以我想动态使用需求,并初始化变量,我该怎么做?

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

easyGrid({
    gridName: "protocolSelectedCollection"
});

在上面的代码中,例如,我想要 / collections / 中的不同文件,具体取决于组件,我还想命名 gridName 不同。
那么,我该怎么办呢?如有必要,我会发布更多代码或明确任何疑问 所以这是完整的组件,它非常小。

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>
        );
    }

});

1 个答案:

答案 0 :(得分:2)

如果您的组件非常相似,您可以创建one single component来执行某些操作并根据道具呈现一些结果。

只是传递一些道具。在组件内部,您可以像分别在这3个组件中那样执行操作。在这里,我试图演示如何使用props来呈现来自相同组件的不同结果:

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
  }
}

在主要组件中使用此组件与不同的道具:

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>
     )
  }
}

这只是使用道具的演示。你可以从这里得出这个想法。以下是codepen的一个工作示例:

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

你可以玩它。