【问题标题】:React-select multi select update a prop when no value is selectedReact-select multi select 在未选择任何值时更新道具
【发布时间】:2021-01-09 00:02:35
【问题描述】:

我正在使用 react-select 库来创建多选菜单。当没有选择值时,我希望在 div 上使用某种样式宽度,并且当用户开始从选择下拉列表中选择值时,我希望将此宽度设置为 null,以便选择组件可以使用它自己的自动调整宽度能力。我有下面的代码,但我无法获得同步更新的宽度,因为它在下一次渲染调用后更新。不知道如何让它立即更新为新的宽度。我知道 setState 是异步的,但如果你在 setState 函数中使用回调,我想它会以新状态呈现。

...
constructor(props) {
    super(props);
    this.state = {
        dropBoxWidth: { width: 130 },
        selectLength: 1
    }
}
.....
handleChange = selectedOption => {
    if (this.state.selectLength > 0) {
        this.setState(
            { selectedOption, selectLength: selectedOption.length, dropBoxWidth: null },
            () => console.log(`Option selected:`, this.state.selectedOption, this.state.selectLength, this.state.dropBoxWidth)
        );
    } else {
        this.setState({ dropBoxWidth: { width: 130 }, selectLength: 1 }), () =>
            console.log("New Dropbox Width ", this.state.dropBoxWidth)
    }

};
render() {
    return (
        <div style={this.state.dropBoxWidth}>
            <Select
                closeMenuOnSelect={false}
                isMulti
                options={aList}
                onChange={this.handleChange}
                placeholder="Item Select"
            />
        </div>
    )
}

再次明确,当没有选择值时,我希望将 div 的样式宽度设置为 130。这可能是在页面打开或刷新时(构造函数 props 的宽度为 130),如果用户选择值然后决定从菜单中清除所有选择。

【问题讨论】:

    标签: javascript reactjs react-select


    【解决方案1】:

    您可以在组件样式中使用初始状态。

    <Select
      options={options}
      styles={{
        container: (provided, state) => ({
          ...provided,
          width: !state.hasValue && "130px",
          borderBottom: "1px dotted pink"
        })
      }}
    />
    

    喜欢这里:https://codesandbox.io/s/amazing-dawn-xwcld?file=/src/App.js:290-517

    React 选择样式文档:https://react-select.com/styles

    【讨论】:

      【解决方案2】:

      您的 console.log 没有打印出您期望的 Dropbox 宽度的原因是它实际上没有作为回调传递。

      如果你格式化setState调用,你会注意到逗号实际上是在右括号之后:

      this.setState({
          dropBoxWidth: { width: 130 },
          selectLength: 1
      }),
      () => console.log("New Dropbox Width ", this.state.dropBoxWidth);
      

      但代码的问题是您在进行this.state.selectLength 比较时使用的是陈旧数据。您对以前的价值并不真正感兴趣,而是对当前的价值感兴趣。 react-select 传递给您的 selectedOption 参数要么是数组,要么是 null,因此您可以直接从那里检查长度(即,您可以使用 this.state.selectLength &gt; 0 代替 this.state.selectLength &gt; 0)。

      但是,由于您提到您对样式和长度感兴趣,因为您想要设置父 div 的样式,您实际上并不需要存储样式或长度 - 您可以只存储选定的选项并派生render()中的状态:

      const selectedStyle = { width: 130 }
      
      class Selector extends React.Component {
        constructor(props) {
          super(props);
          this.state = {
            selectedOption: null,
          };
        }
      
        handleChange = (selectedOption) => {
          // null or object array
          this.setState({ selectedOption });
        };
      
        render() {
          const { selectedOption } = this.state;
          const anythingSelected = selectedOption && selectedOption.length > 0;
      
          return (
            <div style={!anythingSelected ? selectedStyle : null}>
              <Select
                closeMenuOnSelect={false}
                isMulti
                options={aList}
                onChange={this.handleChange}
                placeholder="Item Select"
              />
            </div>
          );
        }
      }
      

      【讨论】:

      • 谢谢。这是很好的反馈,我将尝试以这种方式进行测试。再次感谢
      • 很高兴我能帮上忙!顺便说一句,如果你不熟悉它,const { selectedOption } = 被称为destructuring
      猜你喜欢
      • 2022-08-10
      • 2020-07-26
      • 1970-01-01
      • 1970-01-01
      • 2019-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-10
      相关资源
      最近更新 更多