![](/img/trans.png)
[英]Child component holding on to old prop value despite being passed an updated one
[英]Input value in child component not being updated by setState
在這個應用程序中,我從 Unsplash API 獲取圖像(帶有 Express 后端,React 前端)。 在頁面加載時,會出現一般圖像(在react-infinite-scroll-component
內渲染),如果您搜索,則會調用特殊的 fetch 方法( fetchSearchImages
)來獲取新圖像。 在任何一種情況下,它們都會在react-infinite-scroll-component
實例中呈現。
我的問題是提交包含搜索輸入的表單后,搜索輸入沒有被清除。 在輸入中我有value={props.inputValue}
,並且在父組件中,在提交表單后調用fetchSearchImages
。 在fetchSearchImages
中,我嘗試使用this.setState()
重置輸入值,但輸入中顯示的值保持不變。 我也嘗試在handleSubmit()
else 塊中這樣做,但這也沒有做任何事情。
子搜索輸入組件:
const SearchInput = props => {
const onSubmit = e => {
// Prevents GET request/page refresh on submit
e.preventDefault();
props.onFormSubmit();
};
return (
<form onSubmit={onSubmit}>
<div className="control">
<input autoFocus value={props.inputValue} onChange={e => props.onSearch(e.target.value)} className="input" type="text" placeholder="Search" />
</div>
</form>
);
}
父組件:
export class Images extends Component {
state = {
images: [],
searchImages: [],
count: 4,
page: 1,
searchPage: 1,
term: '',
search: false,
newSearch: false,
blankSearch: false,
inputValue: ''
};
componentDidMount() {
const { page, count } = this.state;
axios
.get(`/api/photos?page=${page}&count=${count}`)
.then(res => this.setState({ images: res.data }));
// To prevent same images being fetched upon scrolling (in the first call to fetchImages)
this.setState({ page: page + count });
}
fetchImages = () => {
const { page, count, images } = this.state;
this.setState({ page: page + 1 });
axios
.get(`/api/photos?page=${page}&count=${count}`)
.then(res =>
this.setState({ images: images.concat(res.data) })
);
}
fetchSearchImages = () => {
const { searchPage, count, term, searchImages } = this.state;
this.setState({ searchPage: searchPage + 1, inputValue: '' });
axios
.get(`/api/photos/search?term=${term}&page=${searchPage}&count=${count}`)
.then(res =>
this.setState({
searchImages: searchImages.concat(res.data.results)
})
);
}
// Necessary to place fetchSearchImages in a setState callback to ensure other state is set first
handleSubmit = () => {
if (!this.state.inputValue) {
this.setState({
images: [],
blankSearch: true,
newSearch: false,
search: false,
searchImages: [],
searchPage: 1,
page: 1,
}, this.fetchImages);
} else {
this.setState({
term: this.state.inputValue,
searchImages: [],
searchPage: 1,
page: 1,
search: true,
newSearch: true
}, this.fetchSearchImages);
}
}
handleInputChange = (e) => {
this.setState({
inputValue: e
});
}
render() {
return (
<>
<SearchInput onSearch={this.handleInputChange} value={this.state.inputValue} onFormSubmit={this.handleSubmit} />
<div className="images">
<InfiniteScroll
dataLength={this.state.blankSearch ? this.state.images.length : (this.state.newSearch || this.state.search) ? this.state.searchImages.length : this.state.images.length}
next={this.state.search ? this.fetchSearchImages : this.fetchImages}
hasMore={true}
loader={
<div className="loader-dots">
<span className="loader-dot"></span>
<span className="loader-dot"></span>
<span className="loader-dot"></span>
<span className="loader-dot"></span>
</div>
}
>
{this.state.newSearch || this.state.search ? this.state.searchImages.map(image =>
<Image key={image.id + Math.random()} image={image} />
) : this.state.blankSearch ? this.state.images.map(image =>
<Image key={image.id + Math.random()} image={image} />
) : this.state.images.map(image =>
<Image key={image.id + Math.random()} image={image} />
)}
</InfiniteScroll>
</div>
</>
);
}
}
看起來您的輸入沒有得到適當的控制。
在您的SearchInput
組件中,您引用了一個無效的道具。 您在父級中調用道具value
,但在子級中將其作為inputValue
引用。
將輸入更改為:
<input autoFocus value={props.value} onChange={e => props.onSearch(e.target.value)} className="input" type="text" placeholder="Search" />
或家長:
<SearchInput onSearch={this.handleInputChange} inputValue={this.state.inputValue} onFormSubmit={this.handleSubmit} />
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.