首页 > 解决方案 > React - 未知道具,即使它们存在于响应中

问题描述

由于在浏览器控制台中收到错误,我在从 API 渲染一些数据时遇到问题。

warning.js:33 Warning: Unknown props `scriptVersionId`, `configVersionId`, `model`, `manufacturer`, `refSubType` on <div> tag. Remove these props from the element.

现在我知道这已被多次询问,但我找不到具体答案。我是来自 Java 背景的 React 新手。

所以它的工作方式如下:

父组件从 API 加载数据:

  loadApplicableConfigsForDevice = (type, currentConfig) => {
    if (type != null && currentConfig != null) {
        console.log(type);
        console.log(currentConfig);
        deviceApi.getConfigs(type, currentConfig)
            .then(availableConfigs => {
                console.log("Response Data " + availableConfigs);
                this.setState({availableConfigs})
            })
    }
}

这会按预期加载数据,浏览器中的响应如下:

[ 
{ 
"name":"Hard Wired - LMU 2630 - Driver ID Car Config",
"scriptVersionId":41,
"configVersionId":12,
"description":"OBD",
"model":"LMU 3030",
"manufacturer":"CalAmp",
"refSubType":"OBD"
},
{ 
"name":"OBD - LMU 3030 - Car Config",
"scriptVersionId":200,
"configVersionId":33,
"description":"OBD",
"model":"LMU 3030",
"manufacturer":"CalAmp",
"refSubType":"OBD"
},
{ 
"name":"OBD - LMU 3030 - Car Config",
"scriptVersionId":200,
"configVersionId":33,
"description":"OBD",
"model":"LMU 3030",
"manufacturer":"CalAmp",
"refSubType":"OBD"
},
{ 
"name":"OBD - LMU 3030 - Large Van Config",
"scriptVersionId":201,
"configVersionId":17,
"description":"OBD",
"model":"LMU 3030",
"manufacturer":"CalAmp",
"refSubType":"OBD"
},
{ 
"name":"OBD - LMU 3030 - Small Van Config",
"scriptVersionId":202,
"configVersionId":16,
"description":"OBD",
"model":"LMU 3030",
"manufacturer":"CalAmp",
"refSubType":"OBD"
},
{ 
"name":"OBD - LMU 3030 - VBus- Car Config",
"scriptVersionId":220,
"configVersionId":12,
"description":"OBD",
"model":"LMU 3030",
"manufacturer":"CalAmp",
"refSubType":"OBD"
},
{ 
"name":"OBD - LMU 3030 - VBus- Car Config",
"scriptVersionId":220,
"configVersionId":12,
"description":"OBD",
"model":"LMU 3030",
"manufacturer":"CalAmp",
"refSubType":"OBD"
},
{ 
"name":"OBD - LMU 3030 - VBus- Car Config",
"scriptVersionId":220,
"configVersionId":12,
"description":"OBD",
"model":"LMU 3030",
"manufacturer":"CalAmp",
"refSubType":"OBD"
},
{ 
"name":"OBD - LMU 3030 - VBus- Large Van Config",
"scriptVersionId":221,
"configVersionId":10,
"description":"OBD",
"model":"LMU 3030",
"manufacturer":"CalAmp",
"refSubType":"OBD"
},
{ 
"name":"OBD - LMU 3030 - VBus- Small Van Config",
"scriptVersionId":222,
"configVersionId":11,
"description":"OBD",
"model":"LMU 3030",
"manufacturer":"CalAmp",
"refSubType":"OBD"
},
{ 
"name":"OBD - LMU 3030 - VBus- Small Van Config",
"scriptVersionId":222,
"configVersionId":11,
"description":"OBD",
"model":"LMU 3030",
"manufacturer":"CalAmp",
"refSubType":"OBD"
}
]

所以我知道 API 调用正在工作,因为它正在获取数据。正如你所看到的,我从响应setState中返回。availableConfigs

然后,我将可用配置从状态向下传递到子组件:

 render() {
    const { availableConfigs } = this.state

 return (
 <Grid.Row>
                <Grid.Column width={10}>
                    <EventStatistics
                        device={device} />
                </Grid.Column>
                <Grid.Column width={6}>
                    <DeviceInfo device={device} configs={availableConfigs} handleDeviceUpdate={this.updateDevice} userPreferences={userPreferences} />
                </Grid.Column>
            </Grid.Row>

在子组件的渲染方法中,我然后获取道具 const { device, userPreferences, configs } = this.props; ,然后将该值传递给下拉对象

<Table.Row>
                        <InfoHeader name='Configuration Version' />
                        <Table.Cell>
                            <Dropdown
                                loading={settingConfig}
                                disabled={!configEditable}
                                placeholder='Set Config Version'
                                options={configs}
                                value={formatConfigName( device )}
                                onChange={this.handleConfigChange} />
                            <EditButton editingEnabled={configEditable} onClick={this.toggleConfigEdit} />
                            {/*{formatConfigName( device )}*/}
                        </Table.Cell>

请注意,我传递{configs}到下拉列表的选项部分。

问题是由于开头提到的错误,选项未显示在下拉列表中。我在父组件中的状态如下所示:

 state = {
    device: {},
    events: []
}

我知道这对某些人来说可能很简单,但我已经为这个问题苦苦思索了好几个小时了。任何帮助将不胜感激!!!

编辑

import React, { Component } from 'react'
import { Table, Label, Dropdown, Button, Segment, Divider, Grid } from 'semantic-ui-react'
import { toast } from 'react-toastify'

import { getAllSimGroups } from 'api/commonApi'
import { setSimGroup, getConfigs } from 'api/deviceApi'
import { formatDate } from 'utils/commonUtils'
import { formatConfigName } from 'utils/deviceUtils'

import { SendCommand } from 'areas/customer-management'
import { PermissionWrapper } from 'common/ui'
import { IssueWizard } from "common/issue-wizard";

class DeviceInfo extends Component {

constructor(props) {
    super(props);
    this.state = {
        simGroups: [],
        configs: [],
        simGroupEditable: false,
        settingSimGroup: false,
        configEditable: false,
        settingConfig: false
    };
}

componentDidMount() {
    getAllSimGroups()
        .then( simGroups => simGroups.map( formatSimGroup ) )
        .then( simGroups => this.setState( { simGroups } ) )
}


toggleSimGroupEdit = () => this.setState( { simGroupEditable: !this.state.simGroupEditable } );

handleSimGroupChange = ( e, data ) => {
    console.log("Configs " + this.state.configs);
    this.setState( { settingSimGroup: true, simGroupEditable: false } );
    const { imei, iccid } = this.props.device;
    setSimGroup( imei, iccid, data.value )
        .then( this.props.handleDeviceUpdate )
        .catch( error => toast.error( error.message ) )
        .then(() => this.setState( { settingSimGroup: false } ) )
};

handleConfigChange = ( e, data ) => {
    console.log( data.value );
    console.log("Configs " + this.state.configs);
    this.setState( { settingConfig: true, configEditable: false } );
    // const {type, config.name} = this.props.device;
    getConfigs(this.props.device.type, this.props.device.config.name)
        .then( this.props.handleDeviceUpdate )
        .catch( error => toast.error( error.message ) )
        .then(() => this.setState( { settingConfig: false } ) )
};

toggleConfigEdit = () => this.setState( { configEditable: !this.state.configEditable } );

render() {
    const { simGroupEditable, simGroups, settingSimGroup, configEditable, settingConfig } = this.state;
    const { device, userPreferences, configs } = this.props;
    const simGroupCode = device.simGroup != null ? device.simGroup.code : 'SimGroup Not Set';

    return (
        <Segment raised>
            <Grid>
                <Grid.Row>
                    <Grid.Column width={8}>
                        <PermissionWrapper responsibilities={userPreferences.responsibilities} responsibility='SEND_SMS' >
                            <SendCommand iccid={device.iccid} />
                        </PermissionWrapper>
                    </Grid.Column>
                    <Grid.Column width={3}></Grid.Column>
                    <Grid.Column width={5}>    
                        <IssueWizard
                            id={device.imei}
                            context='IN_USE'
                            type='DEVICE'
                            trigger={<Button content="Check Device for Issues" size='large' />} 
                        />
                    </Grid.Column>
                </Grid.Row>
            </Grid>
            <Divider />

            <Table size='small' compact singleLine verticalAlign='middle'>
                <Table.Body>
                    <Table.Row>
                        <InfoHeader name='Vehicle Reg' />
                        <Table.Cell>{device.vehReg}</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <InfoHeader name='IMEI' />
                        <Table.Cell>{device.imei}</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <InfoHeader name='First Message' />
                        <Table.Cell>{formatDate( device.activationDate )}</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <InfoHeader name='Last Message' />
                        <Table.Cell>{formatDate( device.lastMessageTime, 'HH:mm DD MMMM YYYY' )}</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <InfoHeader name='Service ID' />
                        <Table.Cell>{device.serviceId}</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <InfoHeader name='ICCID' />
                        <Table.Cell>{device.iccid}</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <InfoHeader name='Sim Group' />
                        <Table.Cell>
                            <Dropdown
                                loading={settingSimGroup}
                                disabled={!simGroupEditable}
                                placeholder='Set Sim Group'
                                options={simGroups}
                                value={settingSimGroup ? 0 : simGroupCode}
                                onChange={this.handleSimGroupChange} />
                            <EditButton editingEnabled={simGroupEditable} onClick={this.toggleSimGroupEdit} />
                        </Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <InfoHeader name='Configuration Status' />
                        <Table.Cell>{device.config ? device.config.status : ''}</Table.Cell>
                    </Table.Row>
                    <Table.Row>
                        <InfoHeader name='Configuration Version' />
                        <Table.Cell>
                            <Dropdown
                                loading={settingConfig}
                                disabled={!configEditable}
                                placeholder='Set Config Version'
                                options={configs}
                                value={formatConfigName( device )}
                                onChange={this.handleConfigChange} />
                            <EditButton editingEnabled={configEditable} onClick={this.toggleConfigEdit} />
                            {/*{formatConfigName( device )}*/}
                        </Table.Cell>
                    </Table.Row>
                </Table.Body>
            </Table>
        </Segment>
    )
}
}

export default DeviceInfo

const InfoHeader = ( { name } ) => (
<Table.Cell width={6}>
    <Label className='fluid text-center' size='medium' color='blue' content={name} />
</Table.Cell>
);

const EditButton = ( { onClick, editingEnabled } ) => (
<Button
    compact
    size='mini'
    negative={editingEnabled}
    floated='right'
    content={editingEnabled ? 'Cancel' : 'Edit'}
    onClick={onClick} />
  );

// const formatConfig = conf => ( { key: conf.name, text: formatConfigName( conf ), value: formatConfigName( conf ) } );

const formatSimGroup = sg => ( { key: sg.id, text: sg.name, value: sg.code } )

标签: reactjsreact-nativestatereact-props

解决方案


好像您正在使用https://react.semantic-ui.com/modules/dropdown/

在这里,选项道具被指定为

Dropdown.Item 道具数组,例如{ text: '', value: '' }

有关每个选项项中允许的键,请参阅https://react.semantic-ui.com/modules/dropdown/ 。

总之:您必须先转换您的配置对象,然后再将其作为选项提供给下拉组件。

像这样的东西可能会起作用:

options={configs.map( config => {text:config.name, value: config})}


推荐阅读