admin管理员组文章数量:1416642
I'm using MUI, and I've got a custom Tooltip around one TextField in a form. As soon as I type anything in that particular TextField, it loses focus. It updates the state of that value of my formData object to the one character I was able to type, so that value is only ever one character long. The other TextFields in my form work as expected. If I replace the custom Tooltip with a standard one, that particular TextField works fine, too. I've replicated the issue on codesandbox. Here's the code I used there:
import { useState } from "react";
import { TextField, Box } from "@mui/material";
import { styled } from "@mui/material/styles";
import Tooltip, { tooltipClasses } from "@mui/material/Tooltip";
export default function App() {
const [formData, setFormData] = useState({
title: "",
name: ""
});
const handleFormChange = (e) => {
const { name, value } = e.target;
setFormData((formData) => {
return {
...formData,
[name]: value
};
});
};
const CustomWidthTooltip = styled(({ className, ...props }) => (
<Tooltip {...props} classes={{ popper: className }} />
))({
[`& .${tooltipClasses.tooltip}`]: {
maxWidth: 400
}
});
return (
<Box ponent="form" display="flex">
// THIS ONE WORKS JUST FINE
<TextField
onChange={handleFormChange}
autoComplete="title"
name="title"
id="title"
label="Title"
required
/>
// THIS ONE IS BROKEN
<CustomWidthTooltip title="Foo">
<TextField
onChange={handleFormChange}
autoComplete="name"
name="name"
id="name"
label="Name"
required
/>
</CustomWidthTooltip>
</Box>
);
}
Thanks for your help, folks! I appreciate you all.
I'm using MUI, and I've got a custom Tooltip around one TextField in a form. As soon as I type anything in that particular TextField, it loses focus. It updates the state of that value of my formData object to the one character I was able to type, so that value is only ever one character long. The other TextFields in my form work as expected. If I replace the custom Tooltip with a standard one, that particular TextField works fine, too. I've replicated the issue on codesandbox. Here's the code I used there:
import { useState } from "react";
import { TextField, Box } from "@mui/material";
import { styled } from "@mui/material/styles";
import Tooltip, { tooltipClasses } from "@mui/material/Tooltip";
export default function App() {
const [formData, setFormData] = useState({
title: "",
name: ""
});
const handleFormChange = (e) => {
const { name, value } = e.target;
setFormData((formData) => {
return {
...formData,
[name]: value
};
});
};
const CustomWidthTooltip = styled(({ className, ...props }) => (
<Tooltip {...props} classes={{ popper: className }} />
))({
[`& .${tooltipClasses.tooltip}`]: {
maxWidth: 400
}
});
return (
<Box ponent="form" display="flex">
// THIS ONE WORKS JUST FINE
<TextField
onChange={handleFormChange}
autoComplete="title"
name="title"
id="title"
label="Title"
required
/>
// THIS ONE IS BROKEN
<CustomWidthTooltip title="Foo">
<TextField
onChange={handleFormChange}
autoComplete="name"
name="name"
id="name"
label="Name"
required
/>
</CustomWidthTooltip>
</Box>
);
}
Thanks for your help, folks! I appreciate you all.
Share Improve this question edited Oct 20, 2021 at 2:09 alec asked Oct 20, 2021 at 0:31 alecalec 731 silver badge6 bronze badges2 Answers
Reset to default 4You're initializing CustomWidthTooltip
inside the App
ponent, which is causing the tooltip to reintialize on local state change.
Whenever the name
is updated inside formData
local state, the TextField
inside the CustomWidthTooltip
ponent is being recreated in the UI, causing the focus loss as a result.
You should move the CustomWidthTooltip
out of the ponent App
.
Updated Code
import "./styles.css";
import { useState } from "react";
import { TextField, Box } from "@mui/material";
import { styled } from "@mui/material/styles";
import Tooltip, { tooltipClasses } from "@mui/material/Tooltip";
const CustomWidthTooltip = styled(({ className, ...props }) => (
<Tooltip {...props} classes={{ popper: className }} />
))({
[`& .${tooltipClasses.tooltip}`]: {
maxWidth: 400
}
});
export default function App() {
const [formData, setFormData] = useState({
title: "",
name: ""
});
console.log("formData", formData);
const handleFormChange = (e) => {
const { name, value } = e.target;
console.log({ name, value });
setFormData((formData) => {
return {
...formData,
[name]: value
};
});
};
return (
<div>
<h3>With a custom tooltip, it's broken:</h3>
<Box ponent="form" display="flex">
<TextField
onChange={handleFormChange}
autoComplete="title"
name="title"
id="title"
label="Title"
required
/>
<CustomWidthTooltip title="Custom Custom Custom Custom Custom Custom">
<TextField
onChange={handleFormChange}
autoComplete="name"
name="name"
id="name"
label="Name"
required
/>
</CustomWidthTooltip>
</Box>
<h3>With a standard tooltip, it works:</h3>
<Box ponent="form" display="flex">
<TextField
onChange={handleFormChange}
autoComplete="title"
name="title"
id="title"
label="Title"
required
/>
<Tooltip title="Standard">
<TextField
onChange={handleFormChange}
autoComplete="name"
name="name"
id="name"
label="Name"
required
/>
</Tooltip>
</Box>
</div>
);
}
As Junaid mentioned, you are re-rendering the tooltip which is why it flashes.
I would personally use their solution and even move custom styled ponents into another file seeing as you will probably want to reuse them elsewhere.
Regardless, another alternative is the useMemo
hook. This is a good opportunity for you to learn about how it can help.
You can leave your CustomWidthTooltip
function where it is but just wrap it in useMemo
:
import { useState, useMemo } from "react";
...
const CustomWidthTooltip = useMemo(
() =>
styled(({ className, ...props }) => (
<Tooltip {...props} classes={{ popper: className }} />
))({
[`& .${tooltipClasses.tooltip}`]: {
maxWidth: 400
}
}),
[listOfDependencies]
);
...
So this will calculate the styled ponent and store it to your variable, but it will not recreate it on subsequent renders. The array as the second parameter ([listOfDependencies]
), is where you can add variables that it should watch. If there is any change to these variables, it will repute CustomWidthTooltip
.
本文标签: javascriptMUI TextField inside Custom Tooltip loses focus when state changesStack Overflow
版权声明:本文标题:javascript - MUI TextField inside Custom Tooltip loses focus when state changes - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745255490a2650072.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论