简体   繁体   中英

Strange behavior of material-ui when component is inside a function

I'm trying to split my code in more functions inside react functional components, so it's clearer to read and maintain the code, ie:

import React, { useEffect, useState } from "react";
import { StyledExchangeRateProvider } from "./styles";
import useUpdateRates from "../../hooks/useUpdateRates";
import {
    FormControl,
    InputLabel,
    MenuItem,
    Select,
    TextField
} from "@material-ui/core";

export default function ExchangeRateProvider() {
    // rates hook
    const ratesContext = useUpdateRates();
    const rates = ratesContext.state.rates;

    // update rate on component did mount
    useEffect(() => {
        async function updateRates() {
            if (!rates) {
                await ratesContext.updateRate();
            }
        }
        updateRates();
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    // save input values
    const [values, setValues] = useState({
        country: "VES",
        amount: "",
        total: ""
    });

    // change values
    const handleChange = event => {
        setValues({
            ...values,
            [event.target.name]: event.target.value
        });
    };

    function Amount() {
        return (
            <TextField
                name="amount"
                variant="filled"
                label="Amount"
                onChange={handleChange}
                value={values.amount}
                fullWidth
            />
        );
    }

    function Country() {
        return (
            <FormControl fullWidth variant="filled" className="input">
                <InputLabel id="Country">Country</InputLabel>
                <Select
                    labelId="Country"
                    id="country"
                    name="country"
                    value={values.country}
                    onChange={handleChange}
                >
                    <MenuItem value="ARS">Argentina</MenuItem>
                    <MenuItem value="BRL">Brazil</MenuItem>
                    <MenuItem value="INR">India</MenuItem>
                    <MenuItem value="VES">Venezuela</MenuItem>
                    <MenuItem value="ZAR">South Africa</MenuItem>
                </Select>
            </FormControl>
        );
    }

    return (
        <StyledExchangeRateProvider>
            <Amount />
            <Country />
        </StyledExchangeRateProvider>
    );
}

In this code, I'm separating in functions what I'll render in this component, so, ie, the Amount function returns a material-ui TextField. It will return more things, but for simplicity of this question, let's consider just this.

This code renders well, and all elements are shown. However, when I type something in the TextField, the cursor moves away from the TextField each caracter I type.

If I move the <TextField... /> away from the Amount function and put it directly in the React Component return (switch the <Amount /> for <TextField... /> ), the TextField works fine.

I've made a CodeSandBox with the behavior: https://codesandbox.io/s/dreamy-brattain-r4irj

My question is: why does it happen and how to fix it maintaining the code separated in functions?

Move Amount and Country Components outside of ExchangeRateProvider and pass data via props. The Issue is because on each render the functions are being recreated

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM