使用Firebase中的对象设置状态

时间:2018-11-16 03:01:01

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

我无法在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需要一个对象数组 具有“值”和“标签”属性。这是我的数据:

enter image description here

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

问题:因为我使用的是“ for in”循环,所以React在更改道具时无法识别。因此,react-select组件不会重新呈现。我该如何传递这些道具(在父组件内或在Search组件内修改它们),以便Search组件重新呈现?

1 个答案:

答案 0 :(得分:1)

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

我认为您使用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;