使用按钮 React 从 Searchbar 中的道具更新状态

Update state from props in Searchbar with button React

我必须做一个带按钮的经典搜索栏。按钮在这里很重要,因为我可以在单击它之后显示我的列表,而不是更早。

我制作了显示带有列表的搜索栏的主要组件。

class MonitorManagement extends React.PureComponent {

    constructor(props, context) {
        super(props, context)

        this.state = {
            isInitialized: false,
            isSearchReady: false,
            searchString: ''
        }
    }

    componentDidMount() {
        this.props.handlers.onGetCaseMonitors()
    }

    componentDidUpdate() {
        if (!this.state.isInitialized && this.props.caseMonitors) {
            this.setState({
                caseMonitors: this.props.caseMonitors,
                isInitialized: true
            })
        }
    }

    componentWillUnmount() {
        this.props.handlers.onClearCaseMonitors()
    }

    onSearch = searchString => {
        const { caseMonitors } = this.props

        const filtered = caseMonitors.filter(({ name }) =>
            name.toLowerCase().includes(searchString)
        )

        this.setState({ caseMonitors: filtered, isSearchReady: true })
    }

    onSearchHandler = () => {
        const { caseMonitors, handlers } = this.props
        const { searchString } = this.state

        this.setState({ isSearchReady: false })

        handlers.onGetCaseMonitors()

        if (caseMonitors) {
            handlers.onClearCaseMonitors()
        }

        if (searchString) {
            return this.onSearch(searchString)
        }

        this.setState({ isInitialized: false })
    }

    onSearchUpdate = searchString => this.setState({ searchString })

    renderSearch = () => {
        const { caseMonitors, searchString } = this.state

        return (
            <Search
                caseMonitors={caseMonitors}
                value={searchString}
                handlers={{
                    onSearchUpdate: this.onSearchUpdate,
                    onSearchHandler: this.onSearchHandler
                }}
            />
        )
    }

    renderList = () => {
        const { caseMonitors } = this.state

        if (!caseMonitors) {
            return <Spinner />
        }

        return (
            <List
                caseMonitors={caseMonitors}
            />
        )
    }

    render() {
        return (
            <div>
                {this.renderSearch()}
                {this.renderList()}
            </div>
        )
    }
}

这是搜索组件

export default class MonitorManagementSearch extends React.Component {

    constructor(props, context) {
        super(props, context)

        this.searchID = 'monitor-management'
    }

    renderSearch = () => (
        <Search
            handlers={{
                onChange: this.props.handlers.onSearchUpdate,
                onSubmit: this.props.handlers.onSearchHandler
            }}
            id={this.searchID}
            isDisabled={!this.props.caseMonitors}
            minLength={3}
            placeholder={i18n.t('toolkit:MONITOR_MANAGEMENT.PLACEHOLDER_SEARCH')}
            value={this.props.searchString} />
    )

    render() {
        return (
            <div>
                {this.renderSearch()}
            </div>
        )
    }
}

我的解决方案有效,但我不满意。我想摆脱 isInitialized 标志。我必须这样做,因为我的道具来自 redux 商店,并且在安装组件时第一次为 null。我想将所有搜索列表保留在我的状态并将其显示在列表组件中。但是一开始是不可能的,因为等于null.

你们有什么改进的想法吗?

将道具分配给状态不是一个好习惯caseMonitors: this.props.caseMonitors

你可以有一个 util getFilteredData ,它执行以下操作

  1. 当没有搜索字符串时,则 return props.caseMonitors
  2. 当有搜索字符串时,然后过滤数据。
renderList = () => {
  if (!props.caseMonitors) {
    return <Spinner />;
  }

  const filteredData= getFilteredData(props.caseMonitors, this.state.searchString);

  return <List caseMonitors={filteredData} />;
};

getFilteredData 实用程序

const getFilteredData = (dataToFilter, searchText) => {
   if(searchText.trim().length === 0){
      return dataToFilter;
   }

    const filteredData = dataToFilter.filter(({ name }) =>
            name.toLowerCase().includes(searchString)
        )

   return filteredData ;
}

您的 filteredData 只是基于状态 searchString 和道具 cashMonitor 的派生状态,因此不需要为它们维护 2 个状态。您可以删除 componentDidUpdateisInitialized 状态,因为它们不需要。

Working Sandbox