Ошибка: инвариантное нарушение: недопустимый тип элемента: ожидается строка .... но получено: undefined.
Рассматриваемый код:
```
DefectDetails = (props) => {
if (props.currentStep != 2) {
return null;
}
return (
<View>
<Text style={styles.title}>Defect Details</Text>
<Text>Record the return state of the asset</Text>
<Picker
onValueChange={(itemValue, itemIndex) => this.setState({returnState:itemValue})}
>
<Picker.item value="null" label="Select return functionality"/>
<Picker.item value="0" label="Working"/>
<Picker.item value="1"label="Unservicable (red)"/>
<Picker.item value="2" label="Requires Attention (amber)"/>
</Picker>
<this.DefectDescription returnState={this.state.returnState}/>
</View>
)
}
DefectDescription = (props) => {
const returnState=this.props.returnState
if (returnState=="1"|returnState=="2") {
return (
<View>
<Text>Describe issue</Text>
<TextInput/>
</View>
) }
return null;
}
Когда я заменяю <this.DefectDescription/>
на ожидаемое возвращаемое значение DefectDescription, все работает нормально. Базовый код был сгенерирован через Expo, и только приложение. js было изменено.
Полный код:
import React, { Component, useEffect } from 'react';
import {
StyleSheet,
TouchableOpacity,
Text,
TextInput,
View,
Button,
CheckBox,
Input,
Picker
} from 'react-native';
import * as assetData from './assets/assetData.json';
class App extends Component {
constructor(props) {
super(props);
this.state = {
asset_id: "TST-001-WD",
currentStep: 1,
assetRecord:assetData,
hasPermission: null,
setHasPermission: null,
scanned: false,
setScanned: false,
returnState:"null",
hasError: false,
}
console.log(this.state.assetRecord);
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
// Test current step with ternary
// _next and _previous functions will be called on button click
_next = () => {
let currentStep = this.state.currentStep;
// If the current step is 1 or 2, then add one on "next" button click
currentStep = currentStep >= 5? 6: currentStep + 1;
this.setState({
currentStep: currentStep
});
}
_prev = () => {
let currentStep = this.state.currentStep;
// If the current step is 2 or 3, then subtract one on "previous" button click
currentStep = currentStep <= 1? 1: currentStep - 1;
this.setState({
currentStep: currentStep,
});
}
previousButton() {
let currentStep = this.state.currentStep;
if(currentStep !==1){
return (
<TouchableOpacity
style={styles.button}
onPress={this._prev}
>
<Text>Previous</Text>
</TouchableOpacity>
);
}
return null;
}
nextButton(){
let currentStep = this.state.currentStep;
if(currentStep <2){
return (
<TouchableOpacity
style={styles.button}
onPress={this._next}
>
<Text>Next</Text>
</TouchableOpacity>
);
}
return null;
}
AssetDetails = (props) => {
if (props.currentStep != 1) {
return null;
}
return (
<View>
<Text style={styles.title}>Asset Details</Text>
<View style={{flexDirection: 'row',}}>
<Text style={styles.label}>Asset Id</Text>
<Text>{this.state.asset_id}</Text>
<TouchableOpacity
style={styles.button}
onPress={this.keyboardEntry}
>
<Text>Keyboard</Text>
</TouchableOpacity>
</View>
<View style={{flexDirection: 'row',}}>
<Text style={styles.label}>Manufacturer</Text>
<Text>{this.state.assetRecord.Manufacturer_name}</Text>
</View>
<View style={{flexDirection: 'row',}}>
<Text style={styles.label}>Product</Text>
<Text>{this.state.assetRecord.Asset_description}</Text>
</View>
<View style={{flexDirection: 'row',}}>
<Text style={styles.label}>Loan status</Text>
<Text>{this.state.assetRecord.loan_status}</Text>
</View>
<View style={{flexDirection: 'row',}}>
<Text style={styles.label}>Asset status</Text>
<Text>{this.state.assetRecord.Asset_Status_name}</Text>
</View>
<View style={{flexDirection: 'row',}}>
<Text style={styles.label}>RAG Status</Text>
<Text>{this.state.assetRecord.ragStatus}</Text>
</View>
</View>
)
}
DefectDetails = (props) => {
if (props.currentStep != 2) {
return null;
}
return (
<View>
<Text style={styles.title}>Defect Details</Text>
<Text>Record the return state of the asset</Text>
<Picker
onValueChange={(itemValue, itemIndex) => this.setState({returnState:itemValue})}
>
<Picker.item value="null" label="Select return functionality"/>
<Picker.item value="0" label="Working"/>
<Picker.item value="1"label="Unservicable (red)"/>
<Picker.item value="2" label="Requires Attention (amber)"/>
</Picker>
<this.DefectDescription returnState={this.state.returnState}/>
</View>
)
}
DefectDescription = (props) => {
const returnState=this.props.returnState
if (returnState=="1"|returnState=="2") {
return (
<View>
<Text>Describe issue</Text>
<TextInput/>
</View>
) }
return null;
}
render() {
return (
<View style={styles.container}>
<View>
<this.AssetDetails
currentStep={this.state.currentStep}
/>
<this.DefectDetails
currentStep={this.state.currentStep}
/>
</View>
<View style={{flexDirection: 'row',}}>
{this.previousButton()}
{this.nextButton()}
</View>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
button: {
alignItems: 'center',
backgroundColor: '#DDDDDD',
padding: 10,
marginBottom: 10
},
title: {
alignItems: 'center',
padding: 10,
marginBottom: 10,
fontWeight: 'bold',
fontSize: 18,
},
label:{
paddingRight: 10,
},
row:{
paddingRight: 10,
flexDirection: 'row',
}
})
export default App;
Файл assetData. json:
{
"Asset_id": "23",
"Manufacturer_id": "44",
"Asset_Category_id": "32",
"Location_id": "7",
"Asset_Status_id": "4",
"Acquired_date": "2014-09-01",
"Disposal_date": "",
"External_Asset_id": "VEH-001-WD",
"Asset_description": "Transit tipper",
"Comment": "Donated - second hand",
"Last_serviced": "2017-04-11",
"Owner_id": "1",
"Serial_no": "",
"Manufacturer_name": "Ford",
"Asset_Category_name": "Vehicle",
"Location_name": "Western Depot",
"Recording": "Miles",
"derived_status": "3",
"RAGColour": "LightGreen",
"loan_status": "Checked out",
"last_miles_hours": "137",
"last_checklist": [{
"faultData": "true",
"lights": "true",
"tyres": "true"
}],
"last_return_time": "0000-00-00 00:00:00",
"category_list": null,
"Asset_Status_name": "Available subject to RAG",
"faultList": [{
"Asset_Defect_id": "7",
"status_id": "3",
"statusText": "Accepted (No action needed)",
"Fault_description": "Cracked windscreen"
}, {
"Asset_Defect_id": "13",
"status_id": "3",
"statusText": "Accepted (No action needed)",
"Fault_description": "The sticker has fallen off the tailgate"
}, {
"Asset_Defect_id": "29",
"status_id": "3",
"statusText": "Accepted (No action needed)",
"Fault_description": "Bonnet catch has fallen off"
}],
"checkList": [{
"checklist_item_id": "3",
"checklist_item_longtext": "Light check includes head lights, stop lights and indicators",
"checklist_item_title": "Lights",
"checklist_item_code": "lights",
"preChecked": ""
}, {
"checklist_item_id": "2",
"checklist_item_longtext": "Tyres must be checked for wear and pressure",
"checklist_item_title": "Tyres",
"checklist_item_code": "tyres",
"preChecked": ""
}]
}
Я новый разработчик с этим набором инструментов, и это, вероятно, что-то очень простое, но я ломал голову над этим уже два дня