使用按钮 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
,它执行以下操作
- 当没有搜索字符串时,则 return props.caseMonitors
- 当有搜索字符串时,然后过滤数据。
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 个状态。您可以删除 componentDidUpdate
和 isInitialized
状态,因为它们不需要。
我必须做一个带按钮的经典搜索栏。按钮在这里很重要,因为我可以在单击它之后显示我的列表,而不是更早。
我制作了显示带有列表的搜索栏的主要组件。
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
,它执行以下操作
- 当没有搜索字符串时,则 return props.caseMonitors
- 当有搜索字符串时,然后过滤数据。
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 个状态。您可以删除 componentDidUpdate
和 isInitialized
状态,因为它们不需要。