防止父状态更改时重新渲染

时间:2021-02-08 05:59:32

标签: reactjs react-native tensorflow tensorflow.js

背景:

我正在使用 react-native 和 tensorflow HOC Camera 为食品构建实时图像分类应用。

我使用这个 tutorial 作为基础,其中包括一个 github 存储库,您可以在其中通过 Expo 进行测试:

基本上,我希望相机预览保持实时状态并实时显示来自 tensorflow 模型的预测。有一个函数可以在每一帧中调用并预测它。 我可以通过 console.log() 实时预测预测,但使用状态变量显示它们会导致相机重新渲染每个预测。

这显然是糟糕的用户体验,因为只有包含预测的文本应该改变,相机不需要重新渲染。我试过使用 React.memo() 但它提供了一个“性能提示”并且不能保证相机组件不会重新渲染。

代码:

const handleCameraStream = async(tensor) => {
  const prediction = await mobilenetModel.classify(tensor, 1);

  console.log(`prediction: prediction}`);//works live

  setWord(prediction);//causes rerender of camera
}

}

<View style={styles.container}>
    //Want this to update continuously (every time word is updated)
    <Text style={styles.wordTextField}>{word}</Text> 
    //DON'T want the camera to re-mount every state change
    <TensorflowCamera onReady={(imageAsTensors) => handleCameraStream(imageAsTensors)} /> 
  </View>  
</View>

编辑:我能够通过使用 MobX 来调用 setState 来实现一个简单的全局状态。基本上我在 App.js 中有一个类(WordStore),它被传递到一个 Camera 组件和 TextDisplay 组件。相机组件能够在不触发重新渲染的情况下更改商店的属性,并且 TextDisplay 能够在相机保持安装状态时获得这些更改。

您可以通过克隆 this repo 来尝试一下。

只需 npm installexpo start

3 个答案:

答案 0 :(得分:0)

<TensorflowCamera onReady={(imageAsTensors) => handleCameraStream(imageAsTensors)} />

这可能会导致不必要的 TensorflowCamera 重新渲染,因为您要在包含此代码段的组件的每个渲染上传入一个新函数。您可以直接传入 handleCameraStream 或使用 useCallback 钩子将其包裹起来。

答案 1 :(得分:0)

您可以创建一个子组件并用 memo 包裹或使用 useEffect 来避免在 prop 更改时重新渲染。

答案 2 :(得分:0)

通过使用 MobX 来实现一个简单的全局状态,我能够绕过调用 setState 的方法。基本上我在 App.js 中有一个类(WordStore),它被传递到一个 Camera 组件和 TextDisplay 组件。相机组件能够在不触发重新渲染的情况下更改商店的属性,并且 TextDisplay 能够在相机保持安装状态时获得这些更改。

你可以通过克隆这个 repo 来试试:https://github.com/JJwilkin/Pictionary-modification

只需 npm installexpo start