【问题标题】:ReactJS not binding via map to state valuesReactJS 没有通过映射绑定到状态值
【发布时间】:2016-09-15 15:53:56
【问题描述】:

我正在处理一个 MVC5 项目,但遇到了 React 未绑定数组的问题。我在 MVC Core 项目中进行了这项工作,但不得不“回归”到旧结构。最大的变化似乎在控制器中,ajax 调用的返回类型从 JsonResult (Core MVC) 更改为 Json (MVC5)。

以下是 Chrome 开发者工具的输出: (因缺少声望点而被移除)

还有,我的 .jsx 文件代码:

var LineItem = React.createClass({
    render: function () {
        return (
            <div className="gridItem">
                <div className="lessLineHeight smallFont">
                    <div className='section group'>
                        <div className="col span_1_of_2" id={this.props.ordHeaderId}>
                            <text>{this.props.code}</text>
                        </div>
                        <div className='col span_1_of_2 text-right'>
                            <i className={this.props.apptIconString} aria-hidden='true'></i>
                            <i className={this.props.highValueIconString}></i>
                            <i className={this.props.hazmatIconString}></i>
                        </div>
                    </div>
                    <div className='section group'>
                        <div className='col span_6_of_10'>
                            <text title='Trading Partner - Client'>{this.props.tradingPartnerName}</text>
                        </div>
                        <div className='col span_4_of_10 text-right'>
                            <text className='overflowElip' title='Account Manager'>{this.props.accountManager}</text>
                        </div>
                    </div>
                    <div className='section group'>
                        <div className='col span_1_of_2'>
                            <text title={"Origin: " + this.props.originAddress + "; " + this.props.origContact}>{this.props.originAddress}</text>
                        </div>
                        <div className='col span_1_of_2 text-right'>
                            <text title={"Destination:" + this.props.destinationAddress + "; " + this.props.destContact}>{this.props.destinationCity}</text>
                        </div>
                    </div>
                    <div className='section group'>
                        <div className='col span_1_of_3'>${this.props.freightValue}</div>
                        <div className='col span_1_of_3 text-center'>
                            <a title='Promote Order to Load'>To Load</a>
                        </div>
                        <div className='col span_1_of_3 text-right' id={'datePlanned' + this.props.ordHeaderId}>
                            <text title='Pickup Date'>{this.props.dateCreated}</text>
                        </div>
                    </div>
                </div>
            </div>
        );
    }
});

var ItemList = React.createClass({
    getInitialState: function () {
        return { items: [] };
    },
    loadData: function () {
        $.ajax({
            url: this.props.url,
            dataType: 'json',
            success: function (data) {
                console.log(data);
                this.setState({ items: data });
                console.log(this.state.items);
                $("#column1").find(".gridItem:odd").css({ "background-color": "#ddd" }).end().find(".gridItem:even").css({ "background-color": "#fff" });
            }.bind(this),
            error: function (xhr, status, err) {
                console.error(this.props.url, status, err.toString());
            }.bind(this)
        });
    },
    componentDidMount: function () {
        this.loadData();
        /*window.setInterval(this.loadData, this.props.pollInterval);*/
    },
    render: function () {
        if (this.state.items) {
            console.log("State has items.");
            var itemNodes = this.state.items.map(function (foo) {
                return (
                        <LineItem key={foo.ordHeaderId}
                                  accountManager={foo.accountManager}
        apptIconString={foo.apptIconString}
        commodityDescription={foo.commodityDescription}
        commodityId={foo.commodityId}
        dateCreated={foo.dateCreated}
        deliveryAppt={foo.deliveryAppt}
        destContact={foo.destContact}
        destinationAddress={foo.destinationAddress}
        destinationAddressName={foo.destinationAddressName}
        destinationCity={foo.destinationCity}
        earlyDeliveryTime={foo.earlyDeliveryTime}
        earlyPickupTime={foo.earlyPickupTime}
        equipmentName={foo.equipmentName}
        freightValue={foo.freightValue}
        handlingUnits={foo.handlingUnits}
        hazmatIconString={foo.hazmatIconString}
        highValueIconString={foo.highValueIconString}
        isHazmat={foo.isHazmat}
        isHighValue={foo.isHighValue}
        lateDeliveryTime={foo.lateDeliveryTime}
        latePickupTime={foo.latePickupTime}
        loadId={foo.loadId}
        loadNum={foo.loadNum}
        loadTmsStatus={foo.loadTmsStatus}
        ordHeaderId={foo.ordHeaderId}
        ordNum={foo.ordNum}
        orderType={foo.orderType}
        origContact={foo.originContact}
        originAddress={foo.originAddress}
        originAddressName={foo.originAddressName}
        originationCity={foo.originationCity}
        pickupAppt={foo.pickupAppt}
        pieces={foo.pieces}
        plannedEnd={foo.plannedEnd}
        plannedStart={foo.plannedStart}
        requiredTemp={foo.requiredTemp}
        specialInstructions={foo.specialInstructions}
        targetCost={foo.targetCost}
        teamId={foo.teamId}
        tempControlled={foo.tempControlled}
        tradingPartnerNameCNum={foo.tradingPartnerNameCNum}
        tradingPartnerName={foo.tradingPartnerNameClient}
        transportMode={foo.transportMode}
        user3gIdBookedBy={foo.user3gIdBookedBy}
        user3gIdCreatedBy={foo.user3gIdCreatedBy}
        weight={foo.weight} />
                );
            });
            return (
                <div className="itemList">
                    {itemNodes}
                </div>
            );
        } else {
            return null;
        }
    }
});

ReactDOM.render(
    <ItemList url="/DispatchBoard/getColumn1Data" pollInterval={2000} />,
    document.getElementById('column1')
);

从图中可以看出,在 loadData 函数中的 render: 会看到从 ajax 调用返回的项目,然后将它们设置为 state,但是当需要映射它们时,它什么也不做。

对我没有看到的东西有什么想法吗?

编辑

这是一个屏幕显示,在未能正确映射后显示其中一个 LineItem 中的“未定义”值。 undefined values

编辑#2

这是显示对象已水合且未解析的屏幕截图。 object present, not parsed

【问题讨论】:

  • &lt;LineItem key={foo.ordHeaderId} 行可能ordHeaderId 对所有项目都相同,您可以尝试将var itemNodes = this.state.items.map(function (foo) { 更改为var itemNodes = this.state.items.map(function (foo, index) {,然后将&lt;LineItem key={foo.ordHeaderId} 更改为&lt;LineItem key={index}
  • 嗯,该建议确实消除了“索引”错误,但没有采取任何措施来解决 JSON 数组中没有任何值被水合到 LineItems 中的事实。此外,一旦我可以使 LineItems 水合,响应者的建议将毫无意义,因为 OrdHeaderId 是数据库中的主键(唯一)。
  • 对不起,没有读过这个问题,在var itemNodes = this.state.items.map(function (foo, index) { 添加console.log('item',foo) 并查看正在登录到控制台的内容.. 并将日志放在某个地方供我们查看。
  • 我指的是您在developer console 中看到的日志,而不是在react 选项卡中看到的日志。因为在实际看到数据及其结构之前我不能说太多。
  • 从控制台看它没有解析任何东西。进入它很好,然后只是说'这些不是你要找的机器人'。

标签: asp.net-mvc reactjs react-jsx reactjs.net


【解决方案1】:

看到您在 EDIT #2

中发布的屏幕截图后

问题是您在设置组件属性时从foo 访问数据时使用了不同的属性名称

所以改变它

<LineItem key={foo.ordHeaderId}
  accountManager={foo.accountManager}
  apptIconString={foo.apptIconString}

<LineItem key={foo.ordHeaderId}
  accountManager={foo.AccountManager}
...

应该做的伎俩

即使用 foo 对象中的确切属性名称,而不是使用驼峰式或其他版本。

【讨论】:

    【解决方案2】:

    &lt;ItemList&gt; 渲染中的if 条件错误。应该是这样的

    if(this.state.items.length &gt; 0)

    其他一切看起来都很好。但是,您忘记将key 添加到&lt;LineItem&gt; 组件中

    <LineItem key={foo.ordHeaderId}
     accountManager={foo.accountManager}
     ... />
    

    在这里,您将key 作为prop 传递给&lt;LineItem&gt; 组件,但您忘记将该键从道具设置为父元素。

    var LineItem = React.createClass({
     render: function () {
        return (
            <div className="gridItem" key={this.props.key}>
                <div className="lessLineHeight smallFont">
            ....
         )
     }
    }) 
    

    这应该消除错误/警告

    【讨论】:

    • 我更改了if 语句中的测试以检查length &gt; 0 但这没有效果。事实上,它引发了另一个错误,即 this.props.key 将导致未定义。第一个屏幕截图显示我的项目处于状态,因此它通过了 > 0 测试,只是没有为 LineItem 补水。
    • 尝试在&lt;LineItem&gt; 中的return() 之前执行console.log(this.props),并确保获得相应的所有道具。您很可能没有正确解析响应。
    • 它看起来没有解析任何东西,并且没有任何东西超过 url 和 pollInterval 正在使其成为道具。我会将屏幕截图发布到我的 OP。
    【解决方案3】:

    根据我的经验,您不能将 key 作为道具元素传递。从您的 LineItem 中删除它,看看它是否有效。让警告持续存在。如果可行,您可以想办法稍后删除警告。

    <LineItem 
            accountManager={foo.accountManager}
            apptIconString={foo.apptIconString}
            commodityDescription={foo.commodityDescription}
            commodityId={foo.commodityId}
            dateCreated={foo.dateCreated}
            deliveryAppt={foo.deliveryAppt}
            destContact={foo.destContact}
            destinationAddress={foo.destinationAddress}
            destinationAddressName={foo.destinationAddressName}
            destinationCity={foo.destinationCity}
            earlyDeliveryTime={foo.earlyDeliveryTime}
            earlyPickupTime={foo.earlyPickupTime}
            equipmentName={foo.equipmentName}
            freightValue={foo.freightValue}
            handlingUnits={foo.handlingUnits}
            hazmatIconString={foo.hazmatIconString}
            highValueIconString={foo.highValueIconString}
            isHazmat={foo.isHazmat}
            isHighValue={foo.isHighValue}
            lateDeliveryTime={foo.lateDeliveryTime}
            latePickupTime={foo.latePickupTime}
            loadId={foo.loadId}
            loadNum={foo.loadNum}
            loadTmsStatus={foo.loadTmsStatus}
            ordHeaderId={foo.ordHeaderId}
            ordNum={foo.ordNum}
            orderType={foo.orderType}
            origContact={foo.originContact}
            originAddress={foo.originAddress}
            originAddressName={foo.originAddressName}
            originationCity={foo.originationCity}
            pickupAppt={foo.pickupAppt}
            pieces={foo.pieces}
            plannedEnd={foo.plannedEnd}
            plannedStart={foo.plannedStart}
            requiredTemp={foo.requiredTemp}
            specialInstructions={foo.specialInstructions}
            targetCost={foo.targetCost}
            teamId={foo.teamId}
            tempControlled={foo.tempControlled}
            tradingPartnerNameCNum={foo.tradingPartnerNameCNum}
            tradingPartnerName={foo.tradingPartnerNameClient}
            transportMode={foo.transportMode}
            user3gIdBookedBy={foo.user3gIdBookedBy}
            user3gIdCreatedBy={foo.user3gIdCreatedBy}
            weight={foo.weight} />
    

    【讨论】:

      【解决方案4】:

      随机用户找到了答案,并包含在他的评论中。

      问题的“关键”是没有将要映射的属性大写。不知道为什么它会像在 Core MVC 中那样工作,但显然,它在 MVC 4 中的工作方式不同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-09
        • 2020-04-22
        • 2019-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-09
        相关资源
        最近更新 更多