Reputation: 955
How do I get rid of this warning? I know I need to get rid of setState functions in the render method, but I need them, so where should I put them?
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>
);
}}
Upvotes: 1
Views: 69
Reputation: 2483
No, you don't need to get rid of setState
calls in your render
method in general. You just need to put them so that they are not called in each render call (by binding them to user events like clicks for example) and thereby trigger another re-render, that again calls setState
and again re-renders and so on.
So in your particular case, you are firing setState
right in the beginning in the if() { ... } else { ... }
statements. No matter what this.state.wrapped
is, you end up at setState
.
Here is a possible solution for how you might want to change your code specifically to make it what I assume you want it to make:
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>
);
}}
Because the value of your icon is directly correlated to wrapped
, you don't need to specifically set the icon in the state. Rather infer it from wrapped
.
Upvotes: 2