防止父状态改变时重新渲染
Prevent re-render when the parent state changes
背景:
我正在使用 react-native 和 tensorflow HOC Camera.
构建实时图像 class食品化应用程序
我正在使用这个 tutorial 作为基础,其中包括一个 github 存储库,您可以在其中通过 Expo 对其进行测试:
基本上,我希望相机预览保持实时并实时显示来自 tensorflow 模型的预测。有一个函数调用每一帧并对其进行预测。 我可以 console.log() 实时预测,但使用状态变量显示它们会导致相机重新渲染每个预测。
这显然是糟糕的用户体验,因为只有包含预测的文本应该改变,相机不需要重新渲染。我试过使用 React.memo() 但它提供了 'Performance hint' 并且不保证相机组件不会重新渲染。
代码:
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 中有一个 class (WordStore),它被传递到 Camera 组件和 TextDisplay 组件。相机组件能够在不触发重新渲染的情况下更改商店的属性,并且 TextDisplay 能够在相机保持安装状态时获得这些更改。
您可以通过克隆 this repo 来尝试。
只是 npm install
和 expo start
<TensorflowCamera onReady={(imageAsTensors) => handleCameraStream(imageAsTensors)} />
这可能会导致 TensorflowCamera
不必要的重新呈现,因为您在包含此代码段的组件的每次呈现中都传递了一个新函数。您可以直接传入 handleCameraStream
或使用 useCallback
钩子包装它。
您可以创建一个子组件并用 memo 包装或使用 useEffect 以避免在 prop 更改时重新渲染。
我能够通过使用 MobX 实现简单的全局状态来调用 setState。基本上我在 App.js 中有一个 class (WordStore),它被传递到 Camera 组件和 TextDisplay 组件。相机组件能够在不触发重新渲染的情况下更改商店的属性,并且 TextDisplay 能够在相机保持安装状态时获得这些更改。
您可以通过克隆此存储库来尝试:https://github.com/JJwilkin/Pictionary-modification
只是 npm install
和 expo start
背景:
我正在使用 react-native 和 tensorflow HOC Camera.
构建实时图像 class食品化应用程序我正在使用这个 tutorial 作为基础,其中包括一个 github 存储库,您可以在其中通过 Expo 对其进行测试:
基本上,我希望相机预览保持实时并实时显示来自 tensorflow 模型的预测。有一个函数调用每一帧并对其进行预测。 我可以 console.log() 实时预测,但使用状态变量显示它们会导致相机重新渲染每个预测。
这显然是糟糕的用户体验,因为只有包含预测的文本应该改变,相机不需要重新渲染。我试过使用 React.memo() 但它提供了 'Performance hint' 并且不保证相机组件不会重新渲染。
代码:
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 中有一个 class (WordStore),它被传递到 Camera 组件和 TextDisplay 组件。相机组件能够在不触发重新渲染的情况下更改商店的属性,并且 TextDisplay 能够在相机保持安装状态时获得这些更改。
您可以通过克隆 this repo 来尝试。
只是 npm install
和 expo start
<TensorflowCamera onReady={(imageAsTensors) => handleCameraStream(imageAsTensors)} />
这可能会导致 TensorflowCamera
不必要的重新呈现,因为您在包含此代码段的组件的每次呈现中都传递了一个新函数。您可以直接传入 handleCameraStream
或使用 useCallback
钩子包装它。
您可以创建一个子组件并用 memo 包装或使用 useEffect 以避免在 prop 更改时重新渲染。
我能够通过使用 MobX 实现简单的全局状态来调用 setState。基本上我在 App.js 中有一个 class (WordStore),它被传递到 Camera 组件和 TextDisplay 组件。相机组件能够在不触发重新渲染的情况下更改商店的属性,并且 TextDisplay 能够在相机保持安装状态时获得这些更改。
您可以通过克隆此存储库来尝试:https://github.com/JJwilkin/Pictionary-modification
只是 npm install
和 expo start