【问题标题】:Autocomplete - How can I set a default value?自动完成 - 如何设置默认值?
【发布时间】:2017-07-24 19:49:30
【问题描述】:

有人知道如何为自动完成组件添加默认值吗? 该组件有一个dataSource,我想加载已经选择了特定项目的页面(例如,用所选项目的文本填充文本字段,并且它的值已经设置)。 p>

有人知道怎么做吗?非常感谢您的帮助

【问题讨论】:

    标签: material-ui


    【解决方案1】:

    如果您与过滤器选项一起使用会在每个过滤器上加载 API,这特别棘手。我可以通过在 state 和 onInputChange 选项中设置来加载初始值。

    以下是适用于我的代码,或单击下面的链接查看完整的工作演示。

    https://codesandbox.io/s/smoosh-brook-xgpkq?fontsize=14&hidenavigation=1&theme=dark

    import React, { useState, useEffect } from "react";
    import TextField from "@material-ui/core/TextField";
    import Typography from "@material-ui/core/Typography";
    import Autocomplete from "@material-ui/lab/Autocomplete";
    
    export default function CreateEditStrategy({ match }) {
      const [user, setUser] = useState({
        _id: "32778",
        name: "Magic User's Club!"
      });
      const [filter, setFilter] = useState("");
      const [users, setUsers] = useState([]);
      const [openAutoComplete, setOpenAutoComplete] = React.useState(false);
    
      useEffect(() => {
        (async () => {
          //Will not filter anything for testing purpose
          const response = await fetch(
            `https://api.tvmaze.com/search/shows?q=${filter}`
          );
          const shows = await response.json();
    
          setUsers(
            shows.map((a, i) => {
              return { _id: a.show.id, name: a.show.name };
            })
          );
        })();
      }, [filter]);
      return (
        <div>
          <Typography variant="h6">Autocomplete</Typography>
          <Autocomplete
            open={openAutoComplete}
            onOpen={() => setOpenAutoComplete(true)}
            value={user}
            inputValue={filter}
            onClose={() => setOpenAutoComplete(false)}
            onChange={(event, user) => {
              if (user) setUser(user);
              else setUser({ _id: "", name: "" });
            }}
            onInputChange={(event, newInputValue) => setFilter(newInputValue)}
            getOptionSelected={(option, value) => option.name === value.name}
            getOptionLabel={(option) => option.name}
            options={users}
            renderInput={(params) => (
              <TextField
                {...params}
                label="Asynchronous"
                variant="outlined"
                InputProps={{
                  ...params.InputProps
                }}
              />
            )}
          />
        </div>
      );
    }

    【讨论】:

      【解决方案2】:

      您可以为 AutoComplete 提供 defaultValue 属性。

      <Autocomplete
          multiple
          id="tags-outlined"
          options={
              this.state.categories
          }
          getOptionLabel={(option) => option.category_name
              
          }
          onChange={this.handleAutocomplete}
          defaultValue={'yourDefaultStringValue'} // put your default value here
          filterSelectedOptions
          renderInput={(params) => (
          <TextField
                  fullWidth
              {...params}
              variant="outlined"
              label="Add Categories"
              placeholder="Category"
              required        
          />
      

      【讨论】:

        【解决方案3】:

        这种方法对我有用(使用钩子):

        首先在一个变量中定义你需要的选项:

        const genderOptions = [{ label: 'M' }, { label: 'V' }];
        

        其次,您可以定义一个挂钩来存储所选值(例如将其存储在会话存储中以供页面刷新时使用,或直接使用 useState):

        const age = useSessionStorage('age', '');
        

        接下来,您可以按如下方式定义您的自动完成功能(注意 value 和 getOptionLabel 中的默认值,如果您省略这些,您将获得那些受控到不受控的警告):

          <Autocomplete
            id="id"
            options={ageOptions}
            getOptionLabel={option => option.label || ""}
            value={ageOptions.find(v => v.label === age[0]) || {}} // since we have objects in our options array, this needs to be a object as well
            onInputChange={(_, v) => age[1](v)}
            renderInput={params => (
              <TextField {...params} label="Leeftijd" variant="outlined" />
            )}
          />
        

        【讨论】:

        • 谷歌搜索了一段时间后,我终于找到了解决我问题的答案。谢谢@Simon Temmerman
        【解决方案4】:

        我尝试了上述所有解决方案,但没有任何效果。从那时起,API 可能发生了变化。

        我终于想出了一个解决办法。它不是那么优雅,但原则上它是有道理的。在我的情况下,选项是对象。我只需要使用选项数组中的确切项目设置“值”道具。这样就不需要 componentDidMount 和 getOptionSelected。

        在我们的例子中,自动完成被包裹在另一个组件中。这是主要代码:

        class CTAutoComplete extends React.PureComponent {
        
          getSelectedItem(){
            const item = this.props.options.find((opt)=>{
              if (opt.value == this.props.selectedValue)
                return opt;
            })
            return item || {};
          }
        
          render() {
            return (
                <Autocomplete
                    id={this.props.id}
                    className={this.props.className}
                    style={{ width: '100%' }}
                    options={this.props.options}
                    getOptionLabel={this.props.getOptionLabel}
                    renderInput={params => (
                        <TextField {...params} label={this.props.label} variant="outlined" />
                    )}
                    onChange={this.props.onChange}
                    value={this.getSelectedItem()}
                />
            );
          }
        }
        

        重要提示:设置“value”时,您必须确保输入 null 大小写“|| {}”,否则 React 会抱怨您正在从不受控制的组件更改为受控组件。

        【讨论】:

          【解决方案5】:

          onUpdateInput 为我工作 - 对于任何像我一样浏览这一切的人

          【讨论】:

          • 您好!我已经很久没有使用这个库了;但我会给你一个 +1 的贡献:)
          • 自动完成组件上没有 onUpdateInput 属性。 material-ui.com/api/autocomplete
          【解决方案6】:

          您可以通过在componentDidMount中设置适当的状态来实现这一点,例如:

          componentDidMount() {
              // load your items into your autocomplete
          
              // set your default selected item
              this.setState({ allItems: [itemYouWantToSet], selectedItem: item.name, selectedItemId: item.id }
          }
          
          render() {
              return (
          		<Autocomplete
          		    value={this.state.selectedItem}
          		    items={this.state.allItems}
          		    getItemValue={(item) => item.name}
          		    onSelect={(value, item) => {
          		        this.setState({ selectedItem: value, selectedItemId: value, allItems: [item] });
          		    }}
          		/>
              )
          }

          然后您的项目在加载时从可用选项列表中正确选择。

          【讨论】:

          • 这应该被接受为帮助像我这样的人。根据文档:“该值必须与选项具有引用相等性才能被选中。您可以使用 getOptionSelected 属性自定义相等行为。”如果使用对象数组,则必须使用 value={obj} 属性中的对象。
          • 不确定 API 是否更改,但我在文档中没有看到 Autocomplete 组件的任何 'getItemValue' 属性:material-ui.com/api/autocomplete 刚刚测试并在控制台中获取:“警告:React 没有识别 DOM 元素上的 getItemValue 属性。”
          • 请说明此解决方案适用于哪个 MUI 版本
          【解决方案7】:

          像这样调用你的组件

          <SelectCountryAutosuggest searchText="My Default Value" />
          

          确保在类加载时应用默认值

          class SelectCountryAutosuggest extends React.Component {
            state = {
              value: this.props.searchText, //apply default value instead of ''
              suggestions: [],
            };
          ...
          }
          

          【讨论】:

            【解决方案8】:

            试试这个...

            componentWillReceiveProps(nextProps) {
                let value = nextProps.value
                if (value) {
                  this.setState({
                    value: value
                  })
                }
              }
            

            【讨论】:

              【解决方案9】:

              您是否尝试过动态设置 searchText 属性?您可以将要设置的值作为 searchText 属性传递给自动完成组件。类似的,

              <Autocomplete
                searchText={this.state.input.name} // usually value={this.state.input.name}
              />

              默认情况下,它会在Autocomplete 组件的TextField 中设置初始值,但是当用户进行任何修改时,它会根据dataSource 属性调用自动完成选项。

              【讨论】:

                【解决方案10】:

                您可以使用searchText 属性。

                <AutoComplete searchText="example" ... />
                

                【讨论】:

                • 感谢您的回复。当然,我试过了,但我也想设置它的价值。实际上,我正在寻找一个设置值的道具,并通过设置值来设置 TextField 中的文本。仅设置searchText 的问题是您必须循环所有dataSource 才能找到与文本匹配的值。在我的情况下,我正在使用来自已经具有该值的服务器的数据加载表单,但我需要填充它的 TextField 并设置它的值以防用户不更改字段所以它的字段准备发送。
                • @BetuUuUu 这个问题你解决了吗?我也面临同样的问题
                • 我没有,我一直在填充 searchText 属性,值是通过 redux-form 库设置的。
                猜你喜欢
                • 2019-10-06
                • 2020-10-14
                • 2020-12-08
                • 1970-01-01
                • 1970-01-01
                • 2021-12-15
                • 1970-01-01
                • 2016-05-25
                • 1970-01-01
                相关资源
                最近更新 更多