问题
After upgrading to @material-ui/core 4.11.2, I got warnings with my select components. This is happens because data aren't available at the time I'm rendering the select.
You can see my issue on github: https://github.com/mui-org/material-ui/issues/24041
To correct that, languages
need to be available before rendering the select component.
Now, I want to correct my code, but I'm totally lost, I don't know how to do that.
Here my select component:
<FormControl>
<InputLabel htmlFor="lang">
{localStorage.getItem("lang")}
</InputLabel>
<Select
value={localStorage.getItem("lang")}
onChange={e => this.changeLng(e.target.value, i18n)}
inputProps={{name: "lang", id: "lang"}}
>
{languages &&
languages.map((item, index) => {
return (
<MenuItem key={index} value={item.value}>
{item.name}
</MenuItem>
);
})}
</Select>
</FormControl>
Below the componentWillMount()
getLanguages.refetch({}).then(({ data }) => {
if (data) {
let langData = data && data.getLanguages;
this.setState({
languages: langData
});
}
});
Below also the changeLng
changeLng = (e, i18n) => {
let arr = ["fr", "en"];
let langList = e;
let { categoryInfo, staticPagesTerms, productsInfo,AdvancedFilter } = this.props;
localStorage.setItem("lang", e);
if(AdvancedFilter && AdvancedFilter !== undefined){
this.props.AdvancedFiltersubmit({
fieldChild: [],
rangeFilter: []
});
}
localStorage.setItem("langList", e);
staticPagesTerms.refetch().then(({ data }) => {});
productsInfo.refetch({ filter: {} }).then(({ data }) => {
})
if (e === "fr") {
document.body.setAttribute("dir", "ltr");
localStorage.setItem("ltr", "ltr");
} else {
if (!arr.includes(e)) {
langList = "en";
localStorage.setItem("langList", e);
} else {
//localStorage.getItem("lang")
}
document.body.setAttribute("dir", "ltr");
localStorage.setItem("ltr", "ltr");
}
i18n.changeLanguage(langList);
this.props.getRefetch({ variables: { categoryRefetch: true } });
};
Any idea how to solve this? Any answers will be appreciated. Thank you in advance.
回答1:
you can try using defaultValue=""
in the <Select />
component like this comment on releated issues.
https://github.com/mui-org/material-ui/issues/18494#issuecomment-718487022
or if it doesn't work try to provide the default MenuItem if languages
data is not available yet. For example
{languages ? (
languages.map((item, index) => {
return (
<MenuItem key={index} value={item.value}>
{item.name}
</MenuItem>
);
})) : (
<MenuItem value="en">
English
</MenuItem>
)
}
I used the value="en" and English as the default value, but you can adjust it with any static data.
回答2:
seems @vigor akbar answer is also not working, then another way is to delay the rendering of the whole <Select>
component. Provide a demo <Select>
component until you get the data of languages
. And when languages
is available then render that required component.
<FormControl>
<InputLabel htmlFor="lang">{localStorage.getItem("lang")}</InputLabel>
{languages ? (
<Select
value={localStorage.getItem("lang")}
onChange={(e) => this.changeLng(e.target.value, i18n)}
inputProps={{ name: "lang", id: "lang" }}>
{languages.map((item, index) => {
return (
<MenuItem key={index} value={item.value}>
{item.name}
</MenuItem>
);
})}
</Select>
) : (
// Default element shown unitl the 'languages' isn't loaded
<Select value={"loading"} placeholder="Loading...">
<MenuItem value="loading">Loading....</MenuItem>
</Select>
)}
</FormControl>
来源:https://stackoverflow.com/questions/65370281/how-to-defer-rendering-of-select-component-from-material-ui