React Native警告:在现有状态转换期间(例如在`render`中)无法更新

时间:2019-09-22 10:21:56

标签: javascript reactjs react-native

如何摆脱此警告?我知道我需要在render方法中摆脱setState函数,但是我需要它们,那么应该将它们放在哪里?

export default class List<T> extends React.PureComponent<ListProps<T>> {
state = { wrapped: false, iconName: "arrow-down" };

render(): React.Node {
    const { rows, renderRow, title, onPress } = this.props;
    if (this.state.wrapped === true) {
        list = undefined;
        this.setState({ iconName: "arrow-up" });
    } else {
        list = rows.map((row, index) => (
            <View key={index} style={index !== rows.length - 1 ? styles.separator : {}}>
                {renderRow(row, index)}
            </View>
        ));
        this.setState({ iconName: "arrow-down" });
    }
    return (
        <TouchableWithoutFeedback>
            <View style={styles.container}>
                <View style={[styles.separator, styles.relative]}>
                    <Text style={styles.title}>{title}</Text>
                    <IconButton
                        style={styles.icon}
                        onPress={() => this.setState({ wrapped: !this.state.wrapped })}
                        name={this.state.iconName}
                        color="black"
                    />
                </View>
                {list}
            </View>
        </TouchableWithoutFeedback>
    );
}}

1 个答案:

答案 0 :(得分:2)

不,您通常不需要摆脱setState方法中的render个调用。您只需要放置它们,以使它们不会在每个渲染调用中被调用(例如,通过将它们绑定到诸如单击之类的用户事件),从而触发另一个重新渲染,再次调用setState并再次重新渲染,然后等等。

因此,在您的特定情况下,您将在setState语句的开头直接触发if() { ... } else { ... }。无论this.state.wrapped是什么,您最终都会在setState处生活。

这是一个可能的解决方案,用于您可能想如何更改代码以使其符合我认为的要求:

export default class List<T> extends React.PureComponent<ListProps<T>> {
state = { wrapped: false };

render(): React.Node {
    const { rows, renderRow, title, onPress } = this.props;
    const { wrapped } = this.state;

    return (
        <TouchableWithoutFeedback>
            <View style={styles.container}>
                <View style={[styles.separator, styles.relative]}>
                    <Text style={styles.title}>{title}</Text>
                    <IconButton
                        style={styles.icon}
                        onPress={() => this.setState({ wrapped: !wrapped })}
                        name={wrapped ? "arrow-up" : "arrow-down"}
                        color="black"
                    />
                </View>
                {!wrapped && (
                  <View key={index} style={index !== rows.length - 1 ? styles.separator : {}}>
                    {renderRow(row, index)}
                  </View>
                )}
            </View>
        </TouchableWithoutFeedback>
    );
}}

由于图标的值与wrapped直接相关,因此您无需专门将图标设置为状态。而是从wrapped推断出来的。