我正在尝试将旧版React Native应用程序(也使用Redux)升级到最新版本,并且遵循以下准则:
这是旧代码库的示例:
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { compose } from 'redux'
import { View, Text } from 'react-native'
import { Colors } from '../../Themes'
import FontAwesome from 'react-native-vector-icons/FontAwesome'
import Octicons from 'react-native-vector-icons/Octicons'
import Feather from 'react-native-vector-icons/Feather'
import AntDesign from 'react-native-vector-icons/AntDesign'
import StatusLabel from '../WcGlobals/StatusLabel'
import OrderItemsList from '../WcGlobals/OrderItemsList'
import CurrencySymbols from '../../Constants/CurrencySymbols'
import FullScreenLoader from '../FullScreenLoader'
import { CapabilitiesSelectors } from '../../Redux/CapabilitiesRedux'
import moment from 'moment'
import Menu, {
MenuTrigger,
MenuOptions,
MenuOption,
renderers
} from 'react-native-popup-menu'
import styles from './Styles/OrderListItemStyle'
const { SlideInMenu } = renderers
class OrderListItem extends Component {
// // Prop type warnings
static propTypes = {
order: PropTypes.object,
index: PropTypes.number,
capabilities: PropTypes.object
}
statuses = [
{ label: 'On Hold', value: 'on-hold' },
{ label: 'Processing', value: 'processing' },
{ label: 'Completed', value: 'completed' },
{ label: 'Pending', value: 'pending' }
]
getOrderStatus = () => {
const { order } = this.props
return this.statuses.filter(
({ value }) => {
if (order.status === 'processing') { return value === 'completed' }
if (order.status === 'completed') { return false }
if (order.status === 'on-hold') { return value === 'completed' || value === 'processing' }
if (order.status === 'pending') { return value !== order.status }
}
)
}
onSelect = (value) => {
const { onUpdate, order } = this.props
onUpdate(order.id, value)
}
render () {
if (this.props.updating) {
return (<FullScreenLoader />)
}
const statuses = this.getOrderStatus()
// console.log(statuses);
const { order, index } = this.props
const date = moment(order.date_created).format('DDMMM YYYY')
const time = moment(order.date_created).format('hh:mmA')
if (!this.props.capabilities.order_status_update && statuses.length !== 0) {
return (
<Menu name={`order-status-${this.props.index}`} renderer={SlideInMenu} style={this.props.index ? styles.listItemContainer : styles.listItemContainerFirst} onSelect={this.onSelect}>
<MenuTrigger>
<View style={styles.listItemRow}>
<View style={styles.orderNameStatusContainer}>
<View style={styles.orderNoCustContainer}>
<Text style={styles.orderName}>{'#' + order.id}</Text>
{ (order.customer_id)
? (<Text style={styles.orderCustomer}>{' (By ' + order.billing.first_name + ' ' + order.billing.last_name + ')' }</Text>)
: (<Text style={styles.orderCustomer}>{' (By Guest)' }</Text>)
}
</View>
<View style={styles.orderStatusItemsContainer}>
<StatusLabel status={order.status} />
</View>
</View>
<View style={styles.orderProductContainer}>
<Octicons size={17} name={'package'} color={Colors.secondaryColor} />
<OrderItemsList items={order.line_items} />
</View>
<View style={[styles.orderDateContainer]}>
<AntDesign size={16.5} name={'clockcircleo'} color={Colors.secondaryColor} /><Text style={styles.orderDate}>{ date + ' | ' + time }</Text>
<View style={styles.orderCommissionContainer}>
<FontAwesome size={17} name={'money'} color={Colors.secondaryColor} /><Text style={styles.orderCommission}> Earnings: {CurrencySymbols[order.currency]}{Math.round(order.vendor_order_details.total_commission * 100) / 100 }</Text>
</View>
</View>
</View>
</MenuTrigger>
<MenuOptions customStyles={{ optionText: styles.slideInOption }}>
<MenuOption key={'00'} value={''} disabled disableTouchable text={'Tap any one of the options below to change the order status'} />
{statuses.map(({ label, value }) => (<MenuOption key={value} value={value} text={label} />))}
</MenuOptions>
</Menu>
)
} else {
return (
<View style={this.props.index ? styles.listItemContainer : styles.listItemContainerFirst} >
<View style={styles.listItemRow}>
<View style={styles.orderNameStatusContainer}>
<View style={styles.orderNoCustContainer}>
<Text style={styles.orderName}>{'#' + order.id}</Text>
{ (order.customer_id)
? (<Text style={styles.orderCustomer}>{' (By ' + order.billing.first_name + ' ' + order.billing.last_name + ')' }</Text>)
: (<Text style={styles.orderCustomer}>{' (By Guest)' }</Text>)
}
</View>
<View style={styles.orderStatusItemsContainer}>
<StatusLabel status={order.status} />
</View>
</View>
<View style={styles.orderProductContainer}>
<Octicons size={17} name={'package'} color={Colors.secondaryColor} /><OrderItemsList items={order.line_items} />
</View>
<View style={[styles.orderDateContainer]}>
<AntDesign size={16.5} name={'clockcircleo'} color={Colors.secondaryColor} /><Text style={styles.orderDate}>{ date + ' | ' + time }</Text>
<View style={styles.orderCommissionContainer}>
<FontAwesome size={17} name={'money'} color={Colors.secondaryColor} /><Text style={styles.orderCommission}>Earnings: {CurrencySymbols[order.currency]}{Math.round(order.vendor_order_details.total_commission * 100) / 100 }</Text>
</View>
</View>
</View>
</View>
)
}
}
}
const mapStateToProps = (state) => {
return {
capabilities: CapabilitiesSelectors.getData(state)
}
}
export default compose(
connect(mapStateToProps)
)(OrderListItem)
我正在尝试遵循本指南:https://react-native-community.github.io/upgrade-helper/?from=0.59.5&to=0.63.2 到目前为止,这是我想出的:
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { compose } from 'redux'
import {Platform, StyleSheet, Text, View} from 'react-native';
import { Colors } from '../../Themes'
import FontAwesome from 'react-native-vector-icons/FontAwesome'
import Octicons from 'react-native-vector-icons/Octicons'
import Feather from 'react-native-vector-icons/Feather'
import AntDesign from 'react-native-vector-icons/AntDesign'
import StatusLabel from '../WcGlobals/StatusLabel'
import OrderItemsList from '../WcGlobals/OrderItemsList'
import CurrencySymbols from '../../Constants/CurrencySymbols'
import FullScreenLoader from '../FullScreenLoader'
import { CapabilitiesSelectors } from '../../Redux/CapabilitiesRedux'
import moment from 'moment'
import Menu, {
MenuTrigger,
MenuOptions,
MenuOption,
renderers
} from 'react-native-popup-menu'
import styles from './Styles/OrderListItemStyle'
const { SlideInMenu } = renderers
const OrderListItem = ({order,index,capabilities}) => {
//class OrderListItem extends Component {
// // Prop type warnings
OrderListItem.propTypes = {
order: PropTypes.object,
index: PropTypes.number,
capabilities: PropTypes.object
}
statuses = [
{ label: 'On Hold', value: 'on-hold' },
{ label: 'Processing', value: 'processing' },
{ label: 'Completed', value: 'completed' },
{ label: 'Pending', value: 'pending' }
]
getOrderStatus = () => {
const { order } = this.props
return this.statuses.filter(
({ value }) => {
if (order.status === 'processing') { return value === 'completed' }
if (order.status === 'completed') { return false }
if (order.status === 'on-hold') { return value === 'completed' || value === 'processing' }
if (order.status === 'pending') { return value !== order.status }
}
)
}
onSelect = (value) => {
const { onUpdate, order } = this.props
onUpdate(order.id, value)
}
render () {
if (this.props.updating) {
return (<FullScreenLoader />)
}
const statuses = this.getOrderStatus()
// console.log(statuses);
const { order, index } = this.props
const date = moment(order.date_created).format('DDMMM YYYY')
const time = moment(order.date_created).format('hh:mmA')
if (!this.props.capabilities.order_status_update && statuses.length !== 0) {
return (
<Menu name={`order-status-${this.props.index}`} renderer={SlideInMenu} style={this.props.index ? styles.listItemContainer : styles.listItemContainerFirst} onSelect={this.onSelect}>
<MenuTrigger>
<View style={styles.listItemRow}>
<View style={styles.orderNameStatusContainer}>
<View style={styles.orderNoCustContainer}>
<Text style={styles.orderName}>{'#' + order.id}</Text>
{ (order.customer_id)
? (<Text style={styles.orderCustomer}>{' (By ' + order.billing.first_name + ' ' + order.billing.last_name + ')' }</Text>)
: (<Text style={styles.orderCustomer}>{' (By Guest)' }</Text>)
}
</View>
<View style={styles.orderStatusItemsContainer}>
<StatusLabel status={order.status} />
</View>
</View>
<View style={styles.orderProductContainer}>
<Octicons size={17} name={'package'} color={Colors.secondaryColor} />
<OrderItemsList items={order.line_items} />
</View>
<View style={[styles.orderDateContainer]}>
<AntDesign size={16.5} name={'clockcircleo'} color={Colors.secondaryColor} /><Text style={styles.orderDate}>{ date + ' | ' + time }</Text>
<View style={styles.orderCommissionContainer}>
<FontAwesome size={17} name={'money'} color={Colors.secondaryColor} /><Text style={styles.orderCommission}> Earnings: {CurrencySymbols[order.currency]}{Math.round(order.vendor_order_details.total_commission * 100) / 100 }</Text>
</View>
</View>
</View>
</MenuTrigger>
<MenuOptions customStyles={{ optionText: styles.slideInOption }}>
<MenuOption key={'00'} value={''} disabled disableTouchable text={'Tap any one of the options below to change the order status'} />
{statuses.map(({ label, value }) => (<MenuOption key={value} value={value} text={label} />))}
</MenuOptions>
</Menu>
)
} else {
return (
<View style={this.props.index ? styles.listItemContainer : styles.listItemContainerFirst} >
<View style={styles.listItemRow}>
<View style={styles.orderNameStatusContainer}>
<View style={styles.orderNoCustContainer}>
<Text style={styles.orderName}>{'#' + order.id}</Text>
{ (order.customer_id)
? (<Text style={styles.orderCustomer}>{' (By ' + order.billing.first_name + ' ' + order.billing.last_name + ')' }</Text>)
: (<Text style={styles.orderCustomer}>{' (By Guest)' }</Text>)
}
</View>
<View style={styles.orderStatusItemsContainer}>
<StatusLabel status={order.status} />
</View>
</View>
<View style={styles.orderProductContainer}>
<Octicons size={17} name={'package'} color={Colors.secondaryColor} /><OrderItemsList items={order.line_items} />
</View>
<View style={[styles.orderDateContainer]}>
<AntDesign size={16.5} name={'clockcircleo'} color={Colors.secondaryColor} /><Text style={styles.orderDate}>{ date + ' | ' + time }</Text>
<View style={styles.orderCommissionContainer}>
<FontAwesome size={17} name={'money'} color={Colors.secondaryColor} /><Text style={styles.orderCommission}>Earnings: {CurrencySymbols[order.currency]}{Math.round(order.vendor_order_details.total_commission * 100) / 100 }</Text>
</View>
</View>
</View>
</View>
)
}
}
}
const mapStateToProps = (state) => {
return {
capabilities: CapabilitiesSelectors.getData(state)
}
}
export default compose(
connect(mapStateToProps)
)(OrderListItem)
现在,运行我的应用程序时出现以下错误:
ERROR [Error: TransformError SyntaxError: /App/Components/OrderListing/OrderListItem.js: Unexpected token, expected ";" (61:12)
59 | }
60 |
> 61 | render () {
| ^
62 | if (this.props.updating) {
63 | return (<FullScreenLoader />)
64 | }]
有什么办法解决这个问题吗?
答案 0 :(得分:1)
类组件在当前版本的React中仍然存在,没有理由用功能组件完全替换它们。但是,如果要执行此操作,则必须意识到该组件是render
函数。您不能在功能组件内部拥有属性和方法。这是一个函数,因此您将需要变量和语句。
此外,您根本不应使用this
。
基本形式为:
const OrderListItem = props => {
return ...
};
OrderListItem.propTypes = { ... };
完整地,它应该类似于以下内容(未经测试)。
const OrderListItem = props => {
const statuses = [
{ label: 'On Hold', value: 'on-hold' },
{ label: 'Processing', value: 'processing' },
{ label: 'Completed', value: 'completed' },
{ label: 'Pending', value: 'pending' }
];
const getOrderStatus = () => {
const { order } = props
return statuses.filter(
({ value }) => {
if (order.status === 'processing') { return value === 'completed' }
if (order.status === 'completed') { return false }
if (order.status === 'on-hold') { return value === 'completed' || value === 'processing' }
if (order.status === 'pending') { return value !== order.status }
}
)
};
const onSelect = (value) => {
const { onUpdate, order } = props;
onUpdate(order.id, value)
};
if (props.updating) {
return (<FullScreenLoader />)
}
const statuses = getOrderStatus()
// console.log(statuses);
const { order, index } = props
const date = moment(order.date_created).format('DDMMM YYYY')
const time = moment(order.date_created).format('hh:mmA')
if (!props.capabilities.order_status_update && statuses.length !== 0) {
return (
<Menu name={`order-status-${props.index}`} renderer={SlideInMenu} style={props.index ? styles.listItemContainer : styles.listItemContainerFirst} onSelect={onSelect}>
<MenuTrigger>
<View style={styles.listItemRow}>
<View style={styles.orderNameStatusContainer}>
<View style={styles.orderNoCustContainer}>
<Text style={styles.orderName}>{'#' + order.id}</Text>
{ (order.customer_id)
? (<Text style={styles.orderCustomer}>{' (By ' + order.billing.first_name + ' ' + order.billing.last_name + ')' }</Text>)
: (<Text style={styles.orderCustomer}>{' (By Guest)' }</Text>)
}
</View>
<View style={styles.orderStatusItemsContainer}>
<StatusLabel status={order.status} />
</View>
</View>
<View style={styles.orderProductContainer}>
<Octicons size={17} name={'package'} color={Colors.secondaryColor} />
<OrderItemsList items={order.line_items} />
</View>
<View style={[styles.orderDateContainer]}>
<AntDesign size={16.5} name={'clockcircleo'} color={Colors.secondaryColor} /><Text style={styles.orderDate}>{ date + ' | ' + time }</Text>
<View style={styles.orderCommissionContainer}>
<FontAwesome size={17} name={'money'} color={Colors.secondaryColor} /><Text style={styles.orderCommission}> Earnings: {CurrencySymbols[order.currency]}{Math.round(order.vendor_order_details.total_commission * 100) / 100 }</Text>
</View>
</View>
</View>
</MenuTrigger>
<MenuOptions customStyles={{ optionText: styles.slideInOption }}>
<MenuOption key={'00'} value={''} disabled disableTouchable text={'Tap any one of the options below to change the order status'} />
{statuses.map(({ label, value }) => (<MenuOption key={value} value={value} text={label} />))}
</MenuOptions>
</Menu>
)
} else {
return (
<View style={props.index ? styles.listItemContainer : styles.listItemContainerFirst} >
<View style={styles.listItemRow}>
<View style={styles.orderNameStatusContainer}>
<View style={styles.orderNoCustContainer}>
<Text style={styles.orderName}>{'#' + order.id}</Text>
{ (order.customer_id)
? (<Text style={styles.orderCustomer}>{' (By ' + order.billing.first_name + ' ' + order.billing.last_name + ')' }</Text>)
: (<Text style={styles.orderCustomer}>{' (By Guest)' }</Text>)
}
</View>
<View style={styles.orderStatusItemsContainer}>
<StatusLabel status={order.status} />
</View>
</View>
<View style={styles.orderProductContainer}>
<Octicons size={17} name={'package'} color={Colors.secondaryColor} /><OrderItemsList items={order.line_items} />
</View>
<View style={[styles.orderDateContainer]}>
<AntDesign size={16.5} name={'clockcircleo'} color={Colors.secondaryColor} /><Text style={styles.orderDate}>{ date + ' | ' + time }</Text>
<View style={styles.orderCommissionContainer}>
<FontAwesome size={17} name={'money'} color={Colors.secondaryColor} /><Text style={styles.orderCommission}>Earnings: {CurrencySymbols[order.currency]}{Math.round(order.vendor_order_details.total_commission * 100) / 100 }</Text>
</View>
</View>
</View>
</View>
)
}
}
OrderListItem.propTypes = {
order: PropTypes.object,
index: PropTypes.number,
capabilities: PropTypes.object
};
const mapStateToProps = (state) => {
return {
capabilities: CapabilitiesSelectors.getData(state)
}
}
export default compose(
connect(mapStateToProps)
)(OrderListItem)
当然,现在您以前的一些方法毫无意义,例如getOrderStatus
可以是:
const statuses = (() => {
const { order } = this.props
return statuses.filter(
({ value }) => {
if (order.status === 'processing') { return value === 'completed' }
if (order.status === 'completed') { return false }
if (order.status === 'on-hold') { return value === 'completed' || value === 'processing' }
if (order.status === 'pending') { return value !== order.status }
}
)
})();
(请注意,这只是一个匿名闭包,应立即调用。通常,与switch-case
相比,order.status
会更好。)
您还可以将帮助程序方法完全移出功能参数,而不是仅将必需的参数传递给props
。这将使它们更易于调试和维护。