カスタムオートコンプリート(オートサジェスト)コンポーネントを作成しました。ハードコードされた文字列の配列をオートコンプリートコンポーネントに渡すとすべて正常に機能しますが、APIからデータを小道具として渡そうとすると、初めて検索しても何も表示されません。結果は、初回の直後に毎回表示されます
さまざまなオプションを試しましたが、ユーザーが初めてデータを検索しているときにデータがなく、オートコンプリートが空の配列でレンダリングされているようです。同じAPIエンドポイントをテストしましたが、検索するたびにデータが返されます。
オートコンプリートを保持するホームコンポーネント
const filteredUsers = this.props.searchUsers.map((item) => item.firstName).filter((item) => item !== null);
const autocomplete = (
<AutoComplete
items={filteredUsers}
placeholder="Search..."
label="Search"
onTextChanged={this.searchUsers}
fieldName="Search"
formName="autocomplete"
/>
);
挿入されたデータをフィルタリングして提案のリストを表示するオートコンプリートコンポーネント。問題はおそらくonTextChange内にあります。
export class AutoComplete extends Component {
constructor(props) {
super(props);
this.state = {
suggestions: [],
text: '',
};
}
// Matching and filtering suggestions fetched from the backend and text that user has entered
onTextChanged = (e) => {
const value = e.target.value;
let suggestions = [];
if (value.length > 0) {
this.props.onTextChanged(value);
const regex = new RegExp(`^${value}`, 'i');
suggestions = this.props.items.sort().filter((v) => regex.test(v));
}
this.setState({ suggestions, text: value });
};
// Update state each time user press suggestion
suggestionSelected = (value) => {
this.setState(() => ({
text: value,
suggestions: []
}));
};
// User pressed the enter key
onPressEnter = (e) => {
if (e.keyCode === 13) {
this.props.onPressEnter(this.state.text);
}
};
render() {
const { text } = this.state;
return (
<div style={styles.autocompleteContainerStyles}>
<Field
label={this.props.placeholder}
onKeyDown={this.onPressEnter}
onFocus={this.props.onFocus}
name={this.props.fieldName}
formValue={text}
onChange={this.onTextChanged}
component={RenderAutocompleteField}
type="text"
/>
<Suggestions
suggestions={this.state.suggestions}
suggestionSelected={this.suggestionSelected}
theme="default"
/>
</div>
);
}
}
const styles = {
autocompleteContainerStyles: {
position: 'relative',
display: 'inline',
width: '100%'
}
};
AutoComplete.propTypes = {
items: PropTypes.array.isRequired,
placeholder: PropTypes.string.isRequired,
onTextChanged: PropTypes.func.isRequired,
fieldName: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
onPressEnter: PropTypes.func.isRequired,
onFocus: PropTypes.func
};
export default reduxForm({
form: 'Autocomplete'
})(AutoComplete);
期待される結果:ユーザーがtextinputを使用して検索するたびに、提案の結果が得られるはずです。実際の結果:初めてのユーザーがtextinputを使用して検索すると、データは取得されません。初めてのデータがそこにある後でのみ
フィルタリングはで行われるため、ハードコーディングされている場合は機能しますが、APIを使用している場合は機能しませんonTextChanged
。ハードコーディングされAutoComplete
ている場合、最初にonTextChanged
(this.props.items.sort().filter(...
)が呼び出されたときに機能する値がありますが、APIを使用すると、APIがitems
戻るまで、この関数が実行された後、propは空になります。
APIからの結果を処理するには、小道具が変更されたときにフィルタリングを行う必要があります。反応ドキュメントは実際にはここで非常によく似たケースをカバーしています(最初の例は使用getDerivedStateFromProps
が不必要に複雑であることを示しているので2番目の例を参照してください)、重要な部分はPureComponent
不必要な再レンダリングを回避するためにを使用し、レンダリングでフィルタリングを行うことです。あなたの場合:
render() {
// Derive your filtered suggestions from your props in render - this way when your API updates your items prop, it will re-render with the new data
const { text } = this.state;
const regex = new RegExp(`^${text}`, 'i');
suggestions = this.props.items.sort().filter((v) => regex.test(v));
...
<Suggestions
suggestions={suggestions}
...
/>
...
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加