reactjs - (React、MaterialUI、Context)MUI 自动完成/TextField 未在挂载时呈现其值
问题描述
我将 Material UI 的 Autocomplete 组件与他们的 TextField 组件结合使用。除了一个问题外,一切都按预期工作。TextField 未在安装时呈现其输入值。我检查了它是否收到了价值,但由于某种原因它不会显示。
我要实现的功能是让表单输入即使在卸载/安装时也保持其值 - 只要根 App 组件保持安装状态。表单的状态位于 Context 中应用程序的顶层。该表单具有我提到的搜索字段、一个 MUI Select 组件和提交按钮。我对 Select 组件做同样的事情,而且工作正常,只是不是 Autocomplete/TextField。这个问题是否与自动完成特别相关?
上下文.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:
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:
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:(
这是有效的)
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;
解决方案
我只是想通了。我将 TextField 作为受控表单组件,传递了 onChange 和 value 道具。我需要使用“onInputChange”和“inputValue”道具来控制自动完成功能。
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:
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;
推荐阅读
- javascript - 请解释此代码如何用于使用 Javascript 的 Matrix Transpose
- vue.js - Datatable onchange中的v-select不能传值
- r - 创建一个矩阵,其奇数行移动 0.5
- python - 未使用 Seaborn 定义的 Y 轴刻度
- javascript - 你可以使用ajax函数将一个变量从jsp发送到一个servlet并在没有表单的情况下同时打开它吗?
- python - 模拟python脚本的子进程
- c# - Microsoft Graph API 将参与者角色分配给在线会议
- numerical-methods - 什么时候应该开始将二次方程视为数值求根中的线性?
- angular - 具有两个公钥的 Angular Stripe 实现取决于帐户类型
- c++ - 使用空标签结构,编译器声称我缺少初始化程序,但我不是