[英](React, MaterialUI, Context) MUI Autocomplete/TextField not rendering it's value on mount
I'm using Material UI's Autocomplete component in conjunction with their TextField component.我将 Material UI 的 Autocomplete 组件与他们的 TextField 组件结合使用。 Everything's working as expected with the exception of one issue.
除了一个问题外,一切都按预期工作。 The TextField is not rendering its input value on mount.
TextField 未在安装时呈现其输入值。 I checked that it's receiving the value, it just won't show for some reason.
我检查了它是否收到了价值,但由于某种原因它不会显示。
The functionality I'm going for is to have the form inputs hold their values even when unmounted/mounted - so long as the root App component stays mounted.我要实现的功能是让表单输入即使在卸载/安装时也保持其值 - 只要根 App 组件保持安装状态。 The state for the form lives at the top level of the app in Context.
表单的 state 位于 Context 中应用程序的顶层。 The form has the search field I mentioned, an MUI Select component, and submit button.
该表单具有我提到的搜索字段、MUI Select 组件和提交按钮。 I'm doing the same thing with the Select component and that's working fine, just not the Autocomplete/TextField.
我正在用 Select 组件做同样的事情,这工作正常,只是不是自动完成/文本字段。 Is this issue related to Autocomplete specifically?
这个问题是否与自动完成特别相关?
Context.js:上下文.js:
import React, { createContext, useState } from 'react';
const initialState = {
autocompleteOptions: [],
cohortInput: 13,
searchInput: '',
};
const Context = createContext([{}, () => {}]);
export const ContextProvider = ({ children }) => {
const [state, setState] = useState(initialState);
return (
<Context.Provider value={[state, setState]}>
{children}
</Context.Provider>
);
}
export default Context;
SearchField.js: SearchField.js:
import React, { useContext } from 'react';
import Autocomplete from '@material-ui/lab/Autocomplete';
import CloseIcon from '@material-ui/icons/Close';
import Context from '../../../Context';
import TextFieldWithAdornment from './TextFieldWithAdornment';
const SearchField = () => {
const [context, setContext] = useContext(Context); // eslint-disable-line
const { autocompleteOptions } = context;
return (
<Autocomplete
closeIcon={<CloseIcon />}
forcePopupIcon={false}
freeSolo={!!autocompleteOptions}
getOptionLabel={option => option}
options={autocompleteOptions}
renderInput={params => <TextFieldWithAdornment {...params} />}
/>
);
};
export default SearchField;
TextFieldWithAdornment.js: TextFieldWithAdornment.js:
import React, { useContext } from 'react';
import SearchIcon from '@material-ui/icons/SearchTwoTone';
import Context from '../../../Context';
import { findMatches } from './helpers';
import { StyledInputAdornment, StyledTextField } from './styles';
const TextFieldWithAdornment = ({ InputProps, ...restProps }) => {
const [context, setContext] = useContext(Context);
const { searchInput } = context;
const handleChange = ({ target: { value } }) => {
const searchInput = value;
const autocompleteOptions = value.length ? findMatches(value) : [];
setContext({ ...context, autocompleteOptions, searchInput });
};
const handleBlur = () => {
setContext({ ...context, autocompleteOptions: [] });
};
const startAdornment = (
<StyledInputAdornment position="start">
<SearchIcon />
</StyledInputAdornment>
);
return (
<StyledTextField
InputProps={{ ...InputProps, startAdornment }}
onBlur={handleBlur}
onChange={handleChange}
value={searchInput}
{...restProps}
/>
);
};
export default TextFieldWithAdornment;
CohortSelect.js:队列选择.js:
(this is working) (这是工作)
import React, { useContext } from 'react';
import Context from '../../../Context';
import {
CohortSelectWrapper,
StyledLabel,
StyledMenuItem,
StyledSelect,
} from './styles';
const CohortSelect = () => {
const [context, setContext] = useContext(Context);
const { cohortInput } = context;
const handleChange = ({ target: { value } }) => {
setContext({ ...context, cohortInput: value });
};
return (
<CohortSelectWrapper>
<StyledLabel>cohort</StyledLabel>
<StyledSelect onChange={handleChange} value={cohortInput}>
<StyledMenuItem value={11}>11</StyledMenuItem>
<StyledMenuItem value={12}>12</StyledMenuItem>
<StyledMenuItem value={13}>13</StyledMenuItem>
<StyledMenuItem value={14}>14</StyledMenuItem>
</StyledSelect>
</CohortSelectWrapper>
);
};
export default CohortSelect;
I just figured this out.我刚刚想通了。 I had the TextField as the controlled form component being passed the onChange & value props.
我将 TextField 作为受控表单组件,传递了 onChange 和 value 道具。 I needed the Autocomplete to be controlled instead, making use of the 'onInputChange' and 'inputValue' props.
我需要使用“onInputChange”和“inputValue”道具来控制自动完成功能。
SearchField.js: SearchField.js:
import React, { useContext } from 'react';
import Autocomplete from '@material-ui/lab/Autocomplete';
import CloseIcon from '@material-ui/icons/Close';
import Context from '../../../Context';
import TextFieldWithAdornment from './TextFieldWithAdornment';
import { findMatches } from './helpers';
const SearchField = () => {
const [context, setContext] = useContext(Context);
const { autocompleteOptions, searchInput } = context;
const handleChange = event => {
if (event) {
const searchInput = event.target.value;
const autocompleteOptions =
event.target.value.length ? findMatches(event.target.value) : [];
setContext({ ...context, autocompleteOptions, searchInput });
}
};
const handleClear = () => {
setContext({ ...context, autocompleteOptions: [] });
};
return (
<Autocomplete
closeIcon={<CloseIcon />}
freeSolo={!!autocompleteOptions}
getOptionLabel={option => option}
inputValue={searchInput}
onClose={handleClear}
onInputChange={handleChange}
options={autocompleteOptions}
renderInput={params => <TextFieldWithAdornment {...params} />}
/>
);
};
export default SearchField;
TextFieldWithAdornment.js: TextFieldWithAdornment.js:
import React, { useContext } from 'react';
import SearchIcon from '@material-ui/icons/SearchTwoTone';
import Context from '../../../Context';
import { StyledInputAdornment, StyledTextField } from './styles';
const TextFieldWithAdornment = ({ InputProps, ...restProps }) => {
const [context, setContext] = useContext(Context);
const handleBlur = () => {
setContext({ ...context, autocompleteOptions: [] });
};
const startAdornment = (
<StyledInputAdornment position="start">
<SearchIcon />
</StyledInputAdornment>
);
return (
<StyledTextField
InputProps={{ ...InputProps, startAdornment }}
onBlur={handleBlur}
{...restProps}
/>
);
};
export default TextFieldWithAdornment;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.