如何以编程方式清除/重置 React-Select?

Posted

技术标签:

【中文标题】如何以编程方式清除/重置 React-Select?【英文标题】:How to programmatically clear/reset React-Select? 【发布时间】:2018-10-28 23:38:27 【问题描述】:

ReactSelect V2V3 似乎有几个 props,例如 clearValueresetValuesetValue。无论我在尝试什么,我都无法以编程方式清除选择。 resetValue 似乎无法从外部访问。

selectRef.setValue([], 'clear')
// or
selectRef.clearValue()

这不会清除当前的选择。

我在这里遗漏了什么还是它还没有完全实现?

【问题讨论】:

可以使用null值 我尝试使用 react-select 并浪费了我的时间。缺少重置表单的简单性,那么为什么要使用它呢?它做得很复杂,教程也是只有制作者才能理解的东西。 是的。与其使用不起作用的 Ref 来设置它,最简单的解决方案就是将值设置为 null。 【参考方案1】:

如果您使用的是react-select,您可以尝试将null 传递给value 属性。

例如:

import React from "react";
import  render  from "react-dom";
import Select from "react-select";

class App extends React.Component 
  constructor(props) 
    super(props);

    const options = [
       value: "one", label: "One" ,
       value: "two", label: "Two" 
    ];

    this.state = 
      select: 
        value: options[0], // "One" as initial value for react-select
        options // all available options
      
    ;
  

  setValue = value => 
    this.setState(prevState => (
      select: 
        ...prevState.select,
        value
      
    ));
  ;

  handleChange = value => 
    this.setValue(value);
  ;

  handleClick = () => 
    this.setValue(null); // here we reset value
  ;

  render() 
    const  select  = this.state;

    return (
      <div>
        <p>
          <button type="button" onClick=this.handleClick>
            Reset value
          </button>
        </p>
        <Select
          name="form-field-name"
          value=select.value
          onChange=this.handleChange
          options=select.options
        />
      </div>
    );
  


render(<App />, document.getElementById("root"));

Here's 一个工作示例。

【讨论】:

请在您的回答中提供一个(简化的)代码示例,因为链接不是永久的。 嘿,我是 react-select 的新手,请问我知道这是在做什么:`select: value: options[0], options @AKJ value: options[0] 部分表示 react-select 将选项 "One" 作为初始值。 (还为此行添加了解释性注释) 我会补充一点,清除值仅适用于 null。如果您传递未定义(就像我一样),选定的值将保持不变.. 没有任何效果。 react-select 是地狱......太复杂了,只是为了重置它。如果我们花一天时间重置选择控件.. 我们应该什么时候提交它?【参考方案2】:

如果它对任何人有帮助,这是我的解决方案:我创建了一个按钮,通过将状态设置回其初始值来清除所选值。

<button onClick=() => this.clearFilters() >Clear</button>

clearFilters()
    this.setState( startTime: null )

下面的完整代码示例:

import React from "react"
import Select from 'react-select';

const timeSlots = [
     value: '8:00', label: '8:00' ,
     value: '9:00', label: '9:00' ,
     value: '10:00', label: '10:00' ,
] 

class Filter extends React.Component 

  constructor()
    super();
    this.state = 
      startTime: null,
    
  
  
  startTime = (selectedTime) => 
    this.setState( startTime: selectedTime );
  

  clearFilters()
    this.setState(
        startTime: null, 
    )
  

  render()
    const  startTime  = this.state;
    
    return(
      <div>
        <button onClick=() => this.clearFilters() >Clear</button>
        <Select
            value=startTime
            onChange=this.startTime
            options=timeSlots
            placeholder='Start time'
        />
      </div>
    )
  



export default Filter

【讨论】:

这不会使用 react-select API 来重置值。【参考方案3】:

如果您在 React Developers 面板中选中 Select 组件,您将看到它被另一个 - 状态管理器包装。因此,您的 ref 基本上是对 State manager 的参考,而不是对 Select 本身的参考。

幸运的是,StateManager 有 state) 和一个值对象,您可以将其设置为您想要的任何值。

例如(这是来自我的项目,resetGroup 是我附加到 DOM 中某个按钮的 onClick 处理程序):

<Select onChange=this.handleGroupSelect 
      options=this.state.groupsName.map(group => 
                  ( label: group, value: group ) )
      instanceId="groupselect"
      className='group-select-container'
      classNamePrefix="select"
      placeholder=this.context.t("Enter name")
      ref=c => (this.groupSelect = c)
/>

    resetGroup = (e) => 
        e.preventDefault()
        this.setState(
            selectedGroupName: ""
        )
        this.groupSelect.state.value.value = ""
        this.groupSelect.state.value.label = this.context.t("Enter name")
    

【讨论】:

【参考方案4】:

我自己也遇到了这个问题,并通过将key 传递给 React-Select 组件并附加了选定的值来解决它。然后,这将强制 ReactSelect 在更新选择时重新呈现自身。

我希望这对某人有所帮助。

import ReactSelect from 'react-select';

...

<ReactSelect
  key=`my_unique_select_key__$selected`
  value=selected || ''
  ...
/>

【讨论】:

真的不错。如果您选择的值为对象,请使用my_unique_select_key__$JSON.stringify(selected) 这可行,但请注意它会使输入失去焦点。如果这很重要,您可以refocus it imperatively。 刚刚value=selected || ''为我解决了这个问题 有人能解释一下selected是什么吗?变量或关键字还是字符串? selected 在您跟踪下拉列表的当前状态时存储在某处的状态中。当用户做出新的选择时,这应该被更新。这将导致键更改并重新渲染组件,因此将当前选择的值传递给它将确保它使用正确的选择来执行此操作,【参考方案5】:

只需将值存储在状态中,然后使用 componentDidUpdate 等以编程方式更改状态...

class Example extends Component 

constructor() 
    super()


state = 
     value: label: 'Default value', key : '001'


render() 
   return(
      <Select
         ...
         value=this.state.value
         ...
      />
   )
)

注意:'value' 应该是一个对象。

【讨论】:

Bravo 注意到 Select 值应该是一个对象。 一些世界上的东西,但也没有用。【参考方案6】:

一个简单的选择是将null 传递给value 属性。

<Select value=null />

【讨论】:

如果您选择此选项,您应该为值创建一个状态,每次更改都会设置该状态,否则您的字段将保持为空【参考方案7】:

这是我使用Hooks以编程方式清除的React-Select V3的工作实现。

您可以在CodeSandbox DEMO 中使用它。欢迎任何反馈。

const initialFormState =  mySelectKey: null ;

const [myForm, setMyForm] = useState(initialFormState);

const updateForm = value => 
  setMyForm( ...myForm, mySelectKey: value );
;

const resetForm = () => 
  setMyForm(initialFormState);
;

return (
  <div className="App">
    <form>

      <Select name = "mySelect"
           options = options
             value = options.filter(( value ) => value === myForm.mySelectKey)
    getOptionLabel = ( label ) => label
    getOptionValue = ( value ) => value
          onChange = ( value ) => updateForm(value) />

      <p>MyForm: JSON.stringify(myForm)</p>

      <input type="button" value="Reset fields" onClick=resetForm />

    </form>
  </div>
);

【讨论】:

我相信这种方法将受控组件转换为不受控组件?有什么办法可以避免这个错误吗?【参考方案8】:

我使用 redux-observable。

初始状态:

firstSelectData: [],
secondSelectData:[],
secondSelectValue: null

我创建了一个用于填充第一个选择的操作。在更改第一个选择时,我会调用一个动作来填充第二个。

在填充成功时首先选择我设置(secondSelectData[]secondSelectValuenull

我设置的第二次选择填充成功(secondSelectValuenull) 在更改第二个选择时,我会调用一个操作来更新 secondSelectValue 与选择的新值

【讨论】:

【参考方案9】:

如果有人使用 Hooks 寻找解决方案。 React-Select V3.05:

const initial_state =  my_field: "" 

const my_field_options = [
     value: 1, label: "Daily" ,
     value: 2, label: "Weekly" ,
     value: 3, label: "Monthly" ,
]

export default function Example()
    const [values, setValues] = useState(initial_state);

    function handleSelectChange(newValue, actionMeta)
        setValues(
            ...values,
            [actionMeta.name]: newValue ? newValue.value : ""
        )
    

    return <Select
               name="my_field"
               inputId="my_field"
               onChange=handleSelectChange
               options=my_field_options
               placeholder=values.my_field
               isClearable=true
           /> 

【讨论】:

【参考方案10】:

对于那些使用函数组件的人,这里有一个基本演示,说明如何根据一些更改/触发器/reduxValue 重置反应选择。

import React,  useState, useEffect  from 'react';
import Select from 'react-select';

const customReactSelect = ( options ) => 
  const [selectedValue, setSelectedValue] = useState([]);


  /**
   * Based on Some conditions you can reset your value
   */
  useEffect(() => 
      setSelectedValue([])
  , [someReduxStateVariable]);

  const handleChange = (selectedVal) => 
    setSelectedValue(selectedVal);
  ;

  return (
    <Select value=selectedValue onChange=handleChange options=options />
  );
;

export default customReactSelect;

【讨论】:

【参考方案11】:

您可以使用 ref 清除 react select 的值。

import React,  useRef  from "react";
import Select from "react-select";

export default function App() 
  const selectInputRef = useRef();

  const onClear = () => 
    selectInputRef.current.select.clearValue();
  ;

  return (
    <div className="App">
      <h1>Select Gender</h1>
      <Select
        ref=selectInputRef
        options=[
           value: "male", label: "Male" ,
           value: "female", label: "Female" 
        ]
      />
      <button onClick=onClear>Clear Value</button>
    </div>
  );

这里是 CodeSandbox link

【讨论】:

它向我显示了一个错误:预期的类型来自属性 'ref',它在类型 'IntrinsicAttributes & IntrinsicClassAttributes>> & Readonly 上声明<...> & 只读<...>' 嗨@Zeeshan Ahmad,你能告诉我如何使用参考清除值而不将它们添加回选项列表??? 如果是import CreatableSelect from 'react-select/creatable',则需要使用creatableSelectRef.current.select.select.clearValue() 如果我们需要使用 ref 也只是重置一个选择框,那么这就是开发人员生命的终结。【参考方案12】:

您可以将值设置为空

   const [selectedValue, setSelectedValue] = useState();
   const [valueList, setValueList] = useState([]); 
   const [loadingValueList, setLoadingValueList] = useState(true);


 useEffect(() => 
       //on page load update valueList and Loading as false
      setValueList(list);
      loadingValueList(false)
    , []);

                                
  const onClear = () => 
     setSelectedValue(null);  // this will reset the selected value
  ;

<Select
       className="basic-single"
       classNamePrefix="select"
       value=selectedValue
       isLoading=loadingValueList
       isClearable=true
       isSearchable=true
       name="selectValue"
       options=valueList
       onChange=(selectedValue) => 
       setSelectedValue(selectedValue)
      />
  <button onClick=onClear>Clear Value</button>

【讨论】:

【参考方案13】:

反应选择/可创建。

该问题明确寻求反应选择/可创建的解决方案。请找到以下代码,该问题的简单答案和解决方案。您可以针对特定任务修改代码。

import CreatableSelect from "react-select/creatable";

const TestAction = (props) => 
  const  buttonLabelView, className  = props;
  const selectInputRef = useRef();

  function clearSelected() 
    selectInputRef.current.select.select.clearValue();
  

  const createOption = (label, dataId) => (
    label,
    value: dataId,
  );

  const Options = ["C1", "C2", "C3", "C4"]?.map((post, id) => 
    return createOption(post, id);
  );

  return (
    <div>
      <CreatableSelect
        ref=selectInputRef
        name="dataN"
        id="dataN"
        className="selctInputs"
        placeholder=" Select..."
        isMulti
        options=Options
      />

      <button onClick=(e) => clearSelected()> Clear </button>
    </div>
  );
;

export default TestAction;

【讨论】:

【参考方案14】:
if you are using formik then use below code to reset react-select value.

useEffect(()=>
formik.setFieldValue("stateName", [])
,[])

Where stateName is html field name.

if you want to change value according to another dropdown/select (countryName) then pass that field value in useEffect array like below

useEffect(()=>
formik.setFieldValue("stateName", [])
,[formik.values.countryName])

【讨论】:

【参考方案15】:
if you are using formik then use below code to reset react-select value.

useEffect(()=>
formik.setFieldValue("stateName", [])
,[])

Where stateName is html field name.

if you want to change value according to another dropdown/select (countryName) then pass that field value in useEffect array like below

useEffect(()=>
formik.setFieldValue("stateName", [])
,[formik.values.countryName])

【讨论】:

【参考方案16】:

在 react-select 的 value 属性中传递 null 将重置它。

【讨论】:

【参考方案17】:

Zeeshan 的回答确实是正确的 - 您可以使用 clearValue() 但是当您这样做时,Select 实例不会像您想象的那样重置为您的 defaultValue 属性。 clearValue() 返回一个通用的Select... 标签,value 中没有数据。

您可能希望在重置时使用 selectOption() 来明确告诉react-select 应该重置为什么值/标签。我如何连接它(使用Next.jsstyled-componentsreact-select):

import  useState, useRef  from 'react'
import styled from 'styled-components'
import Select from 'react-select'

// Basic button design for reset button
const UIButton = styled.button`
  background-color: #fff;
  border: none;
  border-radius: 0;
  color: inherit;
  cursor: pointer;
  font-weight: 700;
  min-width: 250px;
  padding: 17px 10px;
  text-transform: uppercase;
  transition: 0.2s ease-in-out;

  &:hover 
    background-color: lightgray;
  
`

// Using style object `react-select` library indicates as best practice
const selectStyles = 
  control: (provided, state) => (
    ...provided,
    borderRadius: 0,
    fontWeight: 700,
    margin: '0 20px 10px 0',
    padding: '10px',
    textTransform: 'uppercase',
    minWidth: '250px'
  )


export default function Sample() 
  // State for my data (assume `data` is valid)
  const [ currentData, setCurrentData ] = useState(data.initial)

  // Set refs for each select you have (one in this example)
  const regionOption = useRef(null)

  // Set region options, note how I have `data.initial` set here
  // This is so that when my select resets, the data will reset as well
  const regionSelectOptions = [
     value: data.initial, label: 'Select a Region' ,
     value: data.regionOne, label: 'Region One' ,    
  ]

  // Changes data by receiving event from select form
  // We read the event's value and modify currentData accordingly
  const handleSelectChange = (e) => 
    setCurrentData(e.value)
  

  // Reset, notice how you have to pass the selected Option you want to reset
  // selectOption is smart enough to read the `value` key in regionSelectOptions 
  // All you have to do is pass in the array position that contains a value/label obj
  // In my case this would return us to `Select a Region...` label with `data.initial` value
  const resetData = () => 
    regionOption.current.select.selectOption(regionSelectOptions[0])
    setCurrentData(data.initial)
  

  // notice how my `UIButton` for the reset is separate from my select menu
  return(
    <>
    <h2>Select a region</h2>
    <Select 
      aria-label="Region select menu"
      defaultValue= regionSelectOptions[0] 
      onChange= event => handleDataChange(event) 
      options= regionSelectOptions 
      ref= regionOption 
      styles= selectStyles 
    />
    <UIButton 
      onClick= resetData 
    >
      Reset
    </UIButton>
    </>
  )

【讨论】:

【参考方案18】:

除了上面的答案,请注意该值需要为“null”而不是“undefined”才能正确清除。

【讨论】:

【参考方案19】:

地狱的解决方案帮帮我。 这对我有用:

import React,  Component, Fragment  from "react";

import Select from "react-select";
import  colourOptions  from "./docs/data";

export default class SingleSelect extends Component 
  selectRef = null;

  clearValue = () => 
    this.selectRef.select.clearValue();
  ;

  render() 
    return (
      <Fragment>
        <Select
          ref=ref => 
            this.selectRef = ref;
          
          className="basic-single"
          classNamePrefix="select"
          defaultValue=colourOptions[0]
          name="color"
          options=colourOptions
        />
        <button onClick=this.clearValue>clear</button>
      </Fragment>
    );
  

【讨论】:

以上是关于如何以编程方式清除/重置 React-Select?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式清除缓存?

如何以编程方式清除浏览器缓存?

如何在 Android SDK 26 或更高版本上以编程方式重置锁屏密码

您如何以编程方式清除 HTML5 日期字段?

使用 redux-form 和 react-select.creatable 为啥模糊事件会清除输入?

如何以编程方式重置或取消选中 Angular 中的单选按钮?