(React、MaterialUI、Context)MUI 自动完成/TextField 未在挂载时呈现其值

Posted

技术标签:

【中文标题】(React、MaterialUI、Context)MUI 自动完成/TextField 未在挂载时呈现其值【英文标题】:(React, MaterialUI, Context) MUI Autocomplete/TextField not rendering it's value on mount 【发布时间】:2020-07-18 21:56:07 【问题描述】:

我将 Material UI 的 Autocomplete 组件与他们的 TextField 组件结合使用。除了一个问题外,一切都按预期工作。 TextField 未在安装时呈现其输入值。我检查了它是否收到了价值,但由于某种原因它不会显示。

我要实现的功能是让表单输入即使在卸载/安装时也保持其值 - 只要根 App 组件保持安装状态。表单的状态位于 Context 中应用程序的顶层。该表单具有我提到的搜索字段、一个 MUI Select 组件和提交按钮。我正在对 Select 组件做同样的事情,并且工作正常,只是不是 Autocomplete/TextField。此问题是否与自动完成功能特别相关?

Context.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;

队列选择.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;

【问题讨论】:

【参考方案1】:

我刚刚想通了。我将 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;

【讨论】:

以上是关于(React、MaterialUI、Context)MUI 自动完成/TextField 未在挂载时呈现其值的主要内容,如果未能解决你的问题,请参考以下文章

React 和 MaterialUI - 使用论文的 GridLayout

如何在 MaterialUI 4 中使用 react-jss?

使用 MaterialUI 和 Typescript 在 React 中传递给 onKeyPressed 函数的事件的正确类型是啥?

React:MaterialUI Select Component 不显示传递的值

自动完成问题(Material UI + React + Reagent/ClojureScript)

Material UI:React Autocomplete 组件(受控)和 disableCloseOnSelect