Aamosh Dahal
Aamosh Dahal

Reputation: 11

Prevent re-renders on text inputs when used inside a JS based modal in react-native

I was wondering as to know as to how to prevent unwarranted re-renders when I use text inputs inside a JS based modal.

So my modal is based on react-native-js-only-modal. The way this modal works is by updating props whenever there is change in the children component.

Now the issue is that when I have input inside this component, its causing lots of re-render to the children as value props changes. How can I prevent re-render in this scenario. I already tried memoizing the component but it did'nt work

The reason I am using this JS based modal is because I want to show a toolbar above keyboard that allows form navigation, when I display the toolbar using the native modal, the toolbar buttons can't be clicked. Thus, motivating me to go through the route of JS modals.

Let me know if any specific piece of code would be of any interest.

//This is how children is passed
 <View
  {...{ ...item.component.props, children: undefined }}
  style={viewStyle()}
 >
   {item.component.props.children}
 </View>
//This is how update to props takes place.
const Modal = ({
    visible,
    children,
    onCloseRequest,
    style,
    animationIn,
    animationOut,
    duration,
    direction,
    easing,
    dimensions,
    disableBackHandler,
    fullScreen,
    bgcolor = 'background',
}: Props) => {
    const rId = useRef(uniqueid());
    const context = useContext(ContextProvider);

    if (!context) {
        throw new Error('Modal must be used within a Provider');
    }

    useEffect(() => {
        const id = rId.current;
        if (visible) {
            const props = {
                visible,
                children,
                onCloseRequest,
                style,
                animationIn,
                animationOut,
                duration,
                direction,
                easing,
                dimensions,
                disableBackHandler,
                fullScreen,
                bgcolor,
            };
            if (!context.has(id)) {
                context.push({
                    id: id,
                    component: {
                        props: props,
                    },
                });
            } else {
                context.updateProps(props, id);
            }
            context.update();
        } else {
            const item = context.find(id);
            rId.current = uniqueid(); // forget the current element
            if (item) {
                item.component.onHide?.();
                context.remove(id);
                context.update();
            }
        }
    }, [visible, children]);

    useEffect(() => {
        return () => {
            context.remove(rId.current);
            context.update();
        };
    }, []);

    return null;
};

Upvotes: 0

Views: 31

Answers (0)

Related Questions