【问题标题】:Setting State with Objects from Firebase使用 Firebase 中的对象设置状态
【发布时间】:2019-04-19 05:25:34
【问题描述】:

我无法在 React 中设置组件的状态。该组件称为“搜索”并使用 react-select。完整的组件在这里:

class Search extends React.Component {
  constructor(props){
    super(props);
    let options = [];
    for (var x in props.vals){
      options.push({ value: props.vals[x], label: props.vals[x], searchId: x });
    };
    this.state = {
      inputValue: '',
      value: options
    };
  }

  handleChange = (value: any, actionMeta: any) => {
    if(actionMeta.action == "remove-value"){
      this.props.onRemoveSearch({ searchId: actionMeta.removedValue.searchId })
    }
    this.setState({ value });
  };

  handleInputChange = (inputValue: string) => {
    this.setState({ inputValue });
  };

  handleSearch = ({ value, inputValue }) => {
    this.setState({
      inputValue: '',
      value: [...value, createOption(inputValue)], // Eventually like to take this out...
    });
    this.props.onSearch({ inputValue });
  }

  handleKeyDown = (event: SyntheticKeyboardEvent<HTMLElement>) => {
    const { inputValue, value } = this.state;
    if (!inputValue) return;
    switch (event.key) {
      case 'Enter':
      case 'Tab':
        this.handleSearch({
          value,
          inputValue
        });
        event.preventDefault();
    }
  };

  render() {
    const { inputValue, value } = this.state;
    return (
        <div className="search">
            <div className="search__title">Search</div>
            <Tooltip
              content={this.props.tooltipContent}
              direction="up"
              arrow={true}
              hoverDelay={400}
              distance={12}
              padding={"5px"}
              >
              <CreatableSelect
                className={"tags"}
                components={components}
                inputValue={inputValue}
                isMulti
                menuIsOpen={false}
                onChange={this.handleChange}
                onInputChange={this.handleInputChange}
                onKeyDown={this.handleKeyDown}
                placeholder="Add filters here..."
                value={value}
              />
            </Tooltip>
        </div>
    );
  }
}

module.exports = Search;

您可能已经注意到我在构造函数中所做的奇怪事情。那是因为我需要使用我的 firebase 数据库中的数据,它是对象形式的,但是 react-select 需要一个对象数组 具有“值”和“标签”属性。这是我的数据的样子:

为了弥补差距,我编写了一个 for-in 循环,它创建数组(称为选项)并将其传递给 state.value。

问题:因为我正在使用这个“for in”循环,React 无法识别何时更改了 props。因此,react-select 组件不会重新渲染。如何传递这些道具(在父组件或搜索组件内修改它们)以便搜索组件重新渲染?

【问题讨论】:

  • 如果你的组件没有被卸载,构造函数将不会重新运行。因此,除非卸载,否则您的 for in 循环不会重新运行。另一种选择是将选项移动到您的渲染方法中,或者添加一个额外的生命周期方法 componentDidUpdate

标签: javascript arrays reactjs firebase firebase-realtime-database


【解决方案1】:

我建议不要使用value 状态。您所做的只是将道具复制到您的状态中。你可以直接在render()方法中使用props。

我认为您使用 value 状态是因为您需要根据用户操作对其进行更新。在这种情况下,您可以将此状态提升到父组件中。

class Parent extends React.Component {
  constructor() {
    this.state = { value: //structure should be the same as props.vals in ur code };
  }
  render() {
    return (
      <Search vals={this.state.value}/>
    );
  }
}

class Search extends React.Component {
  constructor(props){
    super(props);

    this.state = {
      inputValue: '',
    };
  }

  render() {
    const { inputValue } = this.state;
    const { vals } = this.props;
    let options = [];
    for (var x in vals){
      options.push({ value: vals[x], label: vals[x], searchId: x });
    };
    return (
        <div className="search">
            <div className="search__title">Search</div>
            <Tooltip
              content={this.props.tooltipContent}
              direction="up"
              arrow={true}
              hoverDelay={400}
              distance={12}
              padding={"5px"}
              >
              <CreatableSelect
                value={options}
              />
            </Tooltip>
        </div>
    );
  }
}

module.exports = Search;

【讨论】:

  • 是的,我正在使用值状态,因为 react-select 组件依赖它。您能否举一个简短的例子来说明您将状态“提升”到我的父组件的含义?我怎么能做到这一点?谢谢。
  • 很多事情都取决于我的搜索组件中的“价值”状态,所以我有点不清楚如何提升它。
  • 请查看我更新的答案以获得简短的演示。如果没有深入了解您的代码,我将无法提供有效的演示。您可能还需要更新事件处理函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-20
  • 1970-01-01
  • 2020-11-02
  • 2023-01-29
  • 2019-03-19
  • 1970-01-01
相关资源
最近更新 更多