You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native类组件中用react-native-translator翻译预测数组

类组件中使用react-native-translator翻译预测数组的解决方案

步骤1:扩展组件状态

在组件的state中添加存储翻译结果的字段,用来保存每个预测项的翻译内容:

state = {
    isTfReady: false,
    isModelReady: false,
    predictions: null,
    image: null,
    translatedPredictions: {} // 键为预测的className,值为翻译后的文本
}

步骤2:实现翻译结果回调函数

创建一个方法,在翻译完成后更新组件状态,存储翻译结果:

handleTranslated = (className, translatedText) => {
    this.setState(prevState => ({
        translatedPredictions: {
            ...prevState.translatedPredictions,
            [className]: translatedText
        }
    }))
}

步骤3:修改渲染逻辑,添加翻译组件

你可以选择将翻译结果与原预测项并排显示,或者单独开辟一个翻译结果区域,以下是两种方案:

方案1:与原预测项并排显示

修改render方法中的预测渲染部分:

<View style={styles.predictionWrapper}>
    {isModelReady && image && (
        <Text style={styles.text}>
            Predictions: {predictions ? '' : 'Predicting...'}
        </Text>
    )}
    {isModelReady &&
        predictions &&
        predictions.map(p => (
            <View key={p.className} style={{marginVertical: 8}}>
                {/* 原预测文本 */}
                {this.renderPrediction(p)}
                {/* 翻译组件,针对当前预测的className */}
                <Translator
                    from="en"
                    to="ms"
                    value={p.className}
                    onTranslated={(translated) => this.handleTranslated(p.className, translated)}
                />
                {/* 显示翻译结果,未完成时显示提示 */}
                <Text style={[styles.text, {color: '#666'}]}>
                    翻译: {this.state.translatedPredictions[p.className] || '翻译中...'}
                </Text>
            </View>
        ))}
</View>

方案2:单独显示翻译结果区域

在原预测区域下方添加一个新的视图,专门展示翻译后的内容:

{/* 原预测区域 */}
<View style={styles.predictionWrapper}>
    {isModelReady && image && (
        <Text style={styles.text}>
            Predictions: {predictions ? '' : 'Predicting...'}
        </Text>
    )}
    {isModelReady &&
        predictions &&
        predictions.map(p => this.renderPrediction(p))}
</View>

{/* 新增翻译结果区域 */}
{isModelReady && predictions && (
    <View style={[styles.predictionWrapper, {marginTop: 20}]}>
        <Text style={styles.text}>翻译结果:</Text>
        {predictions.map(p => (
            <View key={p.className} style={{marginVertical: 8}}>
                <Translator
                    from="en"
                    to="ms"
                    value={p.className}
                    onTranslated={(translated) => this.handleTranslated(p.className, translated)}
                />
                <Text style={styles.text}>
                    {p.className} → {this.state.translatedPredictions[p.className] || '翻译中...'}
                </Text>
            </View>
        ))}
    </View>
)}

步骤4:移除错误的Hooks方法

删除组件中定义的translateTo方法,类组件中不能使用useState等React Hooks,所有状态都需要通过组件的state管理。

修改后的完整组件代码片段

class Home extends React.Component {
    state = {
        isTfReady: false,
        isModelReady: false,
        predictions: null,
        image: null,
        translatedPredictions: {} // 新增翻译结果存储
    }
    
    async componentDidMount() {
        await tf.ready()
        this.setState({
            isTfReady: true
        })
        this.model = await mobilenet.load()
        this.setState({ isModelReady: true })

        console.log(this.state.isTfReady)
        this.getPermissionAsync()
    }

    getPermissionAsync = async () => {
        if (Constants.platform.ios) {
            const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL)
            if (status !== 'granted') {
                alert('Sorry, we need camera roll permissions to make this work!')
            }
        }
    }

    imageToTensor(rawImageData) {
        const TO_UINT8ARRAY = true
        const { width, height, data } = jpeg.decode(rawImageData, TO_UINT8ARRAY)
        const buffer = new Uint8Array(width * height * 3)
        let offset = 0
        for (let i = 0; i < buffer.length; i += 3) {
            buffer[i] = data[offset]
            buffer[i + 1] = data[offset + 1]
            buffer[i + 2] = data[offset + 2]

            offset += 4
        }

        return tf.tensor3d(buffer, [height, width, 3])
    }

    classifyImage = async () => {
        try {
            const imageAssetPath = Image.resolveAssetSource(this.state.image)
            const response = await fetch(imageAssetPath.uri, {}, { isBinary: true })
            const rawImageData = await response.arrayBuffer()
            const imageTensor = this.imageToTensor(rawImageData)
            const predictions = await this.model.classify(imageTensor)
            // 每次分类新图片时,清空之前的翻译结果
            this.setState({ predictions, translatedPredictions: {} })
            console.log(predictions)
        } catch (error) {
            console.log(error)
        }
    }

    selectImage = async () => {
        try {
            let response = await ImagePicker.launchImageLibraryAsync({
                mediaTypes: ImagePicker.MediaTypeOptions.All,
                allowsEditing: true,
                aspect: [4, 3]
            })
    
            if (!response.canceled) {
                const source = { uri: response.uri }
                this.setState({ image: source })
                this.classifyImage()
            }
        } catch (error) {
            console.log(error)
        }
    }

    renderPrediction = prediction => {
        return (
            <Text key={prediction.className} style={styles.text}> {prediction.className} </Text> 
        )
    }

    // 新增翻译结果处理方法
    handleTranslated = (className, translatedText) => {
        this.setState(prevState => ({
            translatedPredictions: {
                ...prevState.translatedPredictions,
                [className]: translatedText
            }
        }))
    }
    
    render() {
        const { isTfReady, isModelReady, predictions, image, translatedPredictions } = this.state;

        return (
            <View style={styles.container}>
                <StatusBar barStyle='light-content' />
                
                <View style={styles.loadingContainer}>
                    
                    <View style={styles.loadingModelContainer}>
                        {(isTfReady && isModelReady) ? (
                            <Text style={styles.text}> APP IS READY FOR SCANNING! </Text>) : <ActivityIndicator size='small' />}
                    </View>
                </View>

                <TouchableOpacity
                    style={styles.imageWrapper}
                    onPress={isModelReady ? this.selectImage : undefined}>
                    {image && <Image source={image} style={styles.imageContainer} />}

                    {isModelReady && !image && (
                        <Text style={styles.transparentText}>Tap to choose image</Text>
                    )}
                </TouchableOpacity>

                {/* 原预测区域 */}
                <View style={styles.predictionWrapper}>
                    {isModelReady && image && (
                        <Text style={styles.text}>
                            Predictions: {predictions ? '' : 'Predicting...'}
                        </Text>
                    )}
                    {isModelReady &&
                        predictions &&
                        predictions.map(p => this.renderPrediction(p))}
                </View>

                {/* 新增翻译结果区域 */}
                {isModelReady && predictions && (
                    <View style={[styles.predictionWrapper, {marginTop: 20}]}>
                        <Text style={styles.text}>翻译结果:</Text>
                        {predictions.map(p => (
                            <View key={p.className} style={{marginVertical: 8}}>
                                <Translator
                                    from="en"
                                    to="ms"
                                    value={p.className}
                                    onTranslated={(translated) => this.handleTranslated(p.className, translated)}
                                />
                                <Text style={styles.text}>
                                    {p.className} → {translatedPredictions[p.className] || '翻译中...'}
                                </Text>
                            </View>
                        ))}
                    </View>
                )}

                <View style={styles.bottom}>
                    <Button style={styles.text} title='SAVE THIS IMAGE' ></Button>
                </View>

                <Button title='LIVE Scan Now' onPress={() => this.props.navigation.navigate('ScanScreen')}></Button>

            </View>
        )
    }
}

注意事项

  • 确保已正确安装并导入react-native-translator包
  • 在classifyImage方法中,每次获取新的预测结果时,要清空之前的翻译结果,避免旧数据干扰
  • 翻译过程是异步的,所以要显示"翻译中..."的提示,直到翻译完成更新状态

内容的提问来源于stack exchange,提问作者lessy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 12:10:51