how to stop images from rendering on setState

Viewed 370

I have images associated with a counter and based on this increment or decrement in counter, a calculation is done and displayed in a text at the bottom.

The problem is that when I render, the images get rendered again and are loaded again and again and again. which I dont want.

If I dont render, the text will not update with the calculated amount. For the counter I am using react-native-counter.

I have already tried with shouldcomponentupdate, but I want to stop only image rendering, the rest should work.

Please advise.

export default class App extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div>
                <Header
                    backgroundColor="#25D366"
                    leftComponent={
                        <Icon
                            name="menu"
                            size={40}
                            color={"#fff000"}
                            onPress={() => this.props.navigation.openDrawer()}
                        />
                    }
                    centerComponent={{
                        text: "Veg & Fruits",
                        style: {
                            color: "#ffffff",
                            fontSize: 25,
                            fontWeight: "bold",
                        },
                    }}
                    rightComponent={<Icon name="home" color={"#ff0000"} />}
                ></Header>
                /// this is searchbar component,
                <SearchBar
                    fontColor="#ffffff"
                    fontWeight="bold"
                    fontSize={20}
                    iconColor="#c6c6c6"
                    shadowColor="#ffffff"
                    cancelIconColor="#c6c6c6"
                    backgroundColor="#25D366"
                    placeholder="Search here"
                    onChangeText={(text) => {
                        this.setState({ photos: [] });
                        this.state.search = text;
                        this.filterList(this.state.search);
                        console.log("text changed");
                    }}
                    onPressCancel={(text) => {
                        text = "";
                        //this.filterList(text);
                    }}
                    onPress={(text) => {
                        console.log("rendering");
                        console.log("now text is: ", this.state.search);
                    }}
                />
                /// in this view images are displayed using functions
                <View>
                    <ScrollView
                        style={{
                            height: Dimensions.get("window").height - 200,
                        }}
                    >
                        <View
                            key={Date.now()}
                            style={{
                                flex: 1,
                                flexDirection: "column",
                                flexWrap: "wrap",
                            }}
                        >
                            {this.filterList(this.state.search)}
                            {this._renderImages()}
                        </View>
                    </ScrollView>

                    <CalcText tt={total_num} />
                </View>
            </div>
        );
    }
}

class CalcText extends Component {
    constructor(props) {
        super(props);
        this.state = {
            ta: 0,
        };
    }

    shouldComponentUpdate(nextProps) {
        console.log(nextProps.tt);
        if (this.props.tt !== nextProps.tt) {
            console.log("changed");
            return true;
        } else {
            console.log("Not changed");
            return false;
        }
    }

    render() {
        return (
            <View style={{ height: 40, backgroundcolor: "ff0000" }}>
                <Text style={{ fontSize: 26, fontWeight: "bold" }}>
                    Total : {this.props.tt}
                </Text>
            </View>
        );
    }
}
1 Answers

You can create a TextBox component and split it from ImageComponent. In this way the images will not be bound to the state of the component rendering text, and you can safely change TextBox state and text preventing ImageComponent to re-render.

Edit:

Okei, now i get it. I think you have no possibility to do it like this.

Let's formalize the problem:

<Parent>
    <Images calc={functionToCalc} />
    <CalcText totalAmount={this.state.totalAmount}/>
</Parent>

functionToCalc is defined in in <Parent> and update parent state, something like:

const funcToCalc = () => {
   // when condition occurs
   this.setState({
      totalAmount : computedAmount
   })
}

The state of <Parent> has:

this.state : {
    totalAmount: none
} 

Whenever condition (buttonClick?) occurs in <Images/> you run functionToCalc update <Parent> state and rerender <CalcText>. Problem here is that also <Images> will be rerender again as all the parent component will be rerender.

this is one of the way to pass info from siblings in React.

You only have a possibility if you want to prevent <Images> rerendering.

  1. Redux or similar libraries for centralize state

You will move the computed calculation in a Store and <CalcText/> will read that from there. <Images/> component will trigger an action modifying that state but won't listen to that so not being rerender.

Related