【问题标题】:React Native Progress View iOS Doesn't RerenderReact Native Progress View iOS 不会重新渲染
【发布时间】:2017-01-21 04:20:39
【问题描述】:

我正在用 React Native 和 REDUX 构建一个应用程序。我在 React Native 中使用 Progress View iOS 来显示一个非常简单的本地外观进度条。代码如下:

renderProgressBar() {
    if(!!Platform.OS) {
        switch(Platform.OS) {
            case 'ios':
                return (
                    <ProgressViewIOS
                        progress={(this.props.backgroundData.percentageLoaded || 0)}
                        progressTintColor={globalProgressBarTintColor}
                        trackTintColor={globalProgressBarEmptyTrackTintColor} />
                );

            case 'android':
                return (
                    <ProgressBarAndroid
                        color={globalProgressBarTintColor}
                        progress={(this.props.backgroundData.percentageLoaded || 0)} />
                );

            default:
                return null;
        }

    } else {
        return null;
    }
}

我已经在它的 REDUX 容器以及视图本身的这个渲染方法中暂停了应用程序,我 100% 肯定所有进度值都使其正常。它们从我容器中的减速器中显示出来,并被传递到视图中。它们也出现在所有渲染方法中。它们是 0、0.2、0.4、0.666666601、0.8 和 1。

所以我要说的是this.props.backgroundData.percentageLoaded 将等于我刚才提到的这些值。我可以暂停一下,看看这个值肯定在那里,它是一个数字而不是一个字符串,所以一切都应该很好。出于某种原因,即使它渲染了 5 次,也没有任何显示。

它并不落后于其他东西(说 UI 堆栈明智),因为我已将进度值设置为 1 并将颜色设置为栏中的红色和蓝色,它显示得很好。如果我保留那些疯狂的红色/蓝色并将进度设置为我上面提到的所有这些值,它们都会单独工作(硬编码而不是动态道具值)。

如果有人想知道我使用的唯一 React Native 生命周期方法是渲染,它看起来像这样:

render() {
    this.titleWidth = this.props.deviceWidth / 2;

    return (
        <View>
            <View style={[
                            styles.navbar,
                            {
                                width: this.props.deviceWidth,
                                justifyContent: (this.props.showBackIcon === false && this.props.showingTitle === false) ? 'flex-end' : 'space-between',
                            }
                        ]}>

                { this.props.showBackIcon ? this.renderBackButton() : null }

                { this.props.showingTitle ? this.renderTitle() : null }

                { this.props.showingIcon ? this.renderRightIconButton() : null }

                { this.props.showingTextButton ? this.renderRightTextButton() : null }

            </View>

            { this.renderProgressBar() }
        </View>
    );  
}

我被难住了。有人想吗?谢谢。

编辑: 另外,如果有帮助,这里是作为道具发送的容器代码:

const mapStateToProps = (state, props) => {
    return {
        ...safelyBuildPassProps(state.navigation.route.passProps),
        deviceHeight: state.appSettings.deviceOrientation.currDeviceHeight,
        deviceWidth: state.appSettings.deviceOrientation.currDeviceWidth,
        backgroundData: {
            loadingData: state.appSettings.loadingBackgroundData,
            percentageLoaded: state.appSettings.loadingBackgroundDataPercent,
        },
    }
}

二次编辑

我应该进一步解释一下,这一切都基于异步调用和转换。所有流程都发生在客户端(设备)中,流程如下:

  • 使用 fetch 调用后端
  • 获取具有成功状态的响应对象并发送到建模服务
  • 建模服务(这是一个本地 ASync 函数)清理响应对象并使用颜色等转换为适当的 UI 结果
  • 在对响应对象数组进行迭代后,将 100 除以数组长度,然后再除以 100 即可得到 ProgressViewIOS 使用的十进制值。
  • 在完成每个对象的转换后分配百分比
  • Dispatch 调用在进度条所在的导航栏上重新渲染,并将新的百分比传递给它,如上面的代码所示。
  • 发生了重新渲染(我在这里暂停了它以查看它返回正确的 JSX 对象和百分比)但设备中的屏幕上没有任何变化

【问题讨论】:

  • 支持一篇精彩的文章!您确定该应用程序正在返回内部 case 'ios': 并且没有进入 return null 吗?
  • @BradBumbalough 是的,可以肯定的是,我在案例 'ios' 之后放置了一个调试器来观察并确保百分比进入返回的 JSX obj。我也可以肯定地说,我将所有正确的值验证为typeof 'number',使其成为ProgressViewIOS。我唯一还没有尝试过的是进入节点模块,找到ProgressViewIOS 并将调试器放入它的渲染方法中。
  • 哦,对不起,我在所有 return null; 语句上都设置了断点
  • 你试过硬编码 ProgressViewIOS 的 props 吗?
  • 是的,正如我在笔记中描述的那样,我硬编码了“红色”、“蓝色”的值(在 progressTintColortrackTintColor 中)和 5 个数值 0、0.2、0.4 , 0.666666601, 0.8 和 1.

标签: javascript reactjs react-native react-jsx jsx


【解决方案1】:

这里的问题是我试图在不到一秒的时间内更新进度条大约 20 次。有一个进度条来查看数据处理的进度非常棒,但是......如果整个转换发生在一秒钟内......您可能不需要进度条。

一旦我在那里添加更多时间,进度条就有时间更新就好了。

【讨论】: