Skip to content

How can I prevent a react component to render every time parent component renders?

I have a single TextField input on one form, the problem is that when I type on it the displayed/render of the value just typed has a kind of delay, and I want to prevent this.

Context: The TextField is label, name and id come from a state object called ‘formInput’ and they change their value every time a botton is pressed. The value of this single input is stored on a different state object called ‘inputsValue’ that changes inside a ‘handleChange’ function called on the onChange prop of the TextField.

The problem is that Suspicious: I made a “BouncyLetters” component and used it within a component that also renders a form, I use the BouncyLetters for the title of the form. When I remove this component from the page the typing display at normal speed. So I think disabling this from re-rendering always might solve the problem, idk. Thanks

Code:

export const Contact = (props) => {
  const [formInput, setFormInput] = useState({input: 'name', label: 'Type name'});
¿   const [inputsValue, setInputsValue] = useState({name: '', email: '', message: ''});

    const handleClick = () => {
        switch (formInput.input) {
            case 'name':
                setFormInput({ input: 'email', label: 'type email' });
                break; 
            case 'email':
                setFormInput({ input: 'message', label: 'type message' });
                break;
            case 'message':
                setFormInput({ input: 'name', label: 'type name' });
                handleSubmission();
                break;
            default:
                break;
        }
    }
    const handleChange = event => {
        setInputsValue({
            ...inputsValue,
            [event.target.name]: event.target.value
        });
    }
    const handleSubmission = event => {
        console.log('SUBMITTED CONTACT FORM')
    }
  
    return (
        <form>
            <Grid container>
                <Grid item xs={12} sm={10}>
                <BouncyText />
                </Grid>
            </Grid>
            <Grid container spacing={2}>
                <Grid item xs={12} id="contactFomrField">
                    <TextField
                        fullWidth
                        id={formInput.input}
                        label={formInput.label}
                        name={formInput.input}
                        value={inputsValue[formInput.input]}
                        onChange={handleChange}
                    />
                </Grid>
            </Grid>
            <Grid
                container
                justify="center"
                alignItems="center"
            >
                                <Button
                                    onClick={handleClick}
                                    variant="outlined"
                                    color="primary"
                                >
                                    { formInput.input !== 'message' ? 'Next' : 'Send :)'}
                            </Button>
        </form>
    )
}

Answer

handleClick() is a callback(declare in component) pass to child component, so it should be wrapped as useCallback(). otherwise, this callback is redeclare after rerender, so it’s reference is different, make child component reconcile.

https://reactjs.org/docs/hooks-reference.html#usecallback