我正在尝试将一个遗留的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 | }]你知道我该怎么解决这个问题吗?
发布于 2020-08-12 00:35:49
类组件仍然存在于当前版本的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 }
}
)
})();(请注意,这只是一个匿名闭包,会立即调用。一般来说,它作为order.status上的switch-case会工作得更好)。
您还可以将帮助器方法完全移出函数参数,不向它们传递props,而只传递必要的参数。这将使它们更容易调试和维护。
https://stackoverflow.com/questions/63361902
复制相似问题