我还不是React大师,所以我的问题是。如果在子组件中我在输入字段中写新字符,为什么仍要调用父函数?我只想在子组件中单击“搜索”按钮时调用父方法。
父组件:
Error: Uncaught (in promise): DataCloneError: The object can not be cloned. pushState@[native code]
class MainPage extends Component {
render() {
let searchOffersBar = (
<MuiThemeProvider>
<SearchOffer
offersFound={this.props.onOffersFound}
/>
</MuiThemeProvider>
);
let searchResults = (
<SearchResults
offers={this.props.offers}
/>
);
return (
<Aux>
<div className={classes.container}>
<Intro/>
<div className={classes.contentSection}>
{searchOffersBar}
{searchResults}
</div>
</div>
</Aux>
)
}
}
const mapStateToProps = state => {
return {
offers: state.offers.offers
}
}
const mapDispatchToProps = dispatch => {
return {
onOffersFound: (searchParams) => dispatch(actions.fetchOffersByCriteria(searchParams))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(MainPage);
是我的带有搜索部分的子组件(输入字段和“搜索商品”按钮)。我想在输入中填写一些数据,然后单击按钮。尽管单击该按钮将在子组件中调用一个方法:<SearchOffer>
:
onOffersFound
我的动作创建者中的 const searchOffer = props => {
let currentDate = new Date();
const [searchCriteria, setSearchCriteria] = useState({
brand: 'xxx',
capacity: 100
})
const [drawerIsOpen, setDrawerIsOpen] = useState(false);
const handleToggle = () => setDrawerIsOpen(!drawerIsOpen);
const handleBrand = (event) => {
let mergedState = updateObject(searchCriteria, {brand: event.target.value})
setSearchCriteria(mergedState);
}
const handleCapacity = (event) => {
let mergedState = updateObject(searchCriteria, {capacity: event.target.value});
setSearchCriteria(mergedState);
}
const handleBookingFrom = (bookingFromValue) => {
let mergedState = updateObject(searchCriteria, {bookingFrom: bookingFromValue});
setSearchCriteria(mergedState);
}
const handleBookingTo = (bookingToValue) => {
let mergedState = updateObject(searchCriteria, {bookingTo: bookingToValue});
setSearchCriteria(mergedState);
}
return (
<div className={classes.sideNav}>
<Button variant={"outlined"} onClick={handleToggle} className={classes.sideNavBtn}>Search</Button>
<Drawer
className={classes.drawer}
containerStyle={{top: 55}}
docked={false}
width={200}
open={drawerIsOpen}
onRequestChange={handleToggle}
>
<AppBar title="Search"/>
<form noValidate autoComplete="off" onSubmit={props.offersFound(searchCriteria)}>
<MuiPickersUtilsProvider utils={DateFnsUtils}>
<Grid container justify="space-around">
<TextField
id="brand"
label="Brand"
margin="normal"
onChange={handleBrand}
/>
<TextField
id="capacity"
label="Capacity"
margin="normal"
onChange={handleCapacity}
/>
<Button variant="contained" color="primary">
Search
</Button>
</Grid>
</MuiPickersUtilsProvider>
</form>
</Drawer>
</div>
);
}
export default searchOffer;
如下:
onOffersFound
我的问题是,为什么每次我在子组件中输入新字符时都调用上述方法export const fetchOffersByCriteria = (searchParams) => {
return dispatch => {
let queryParams = '?brand='+searchParams.brand + '&capacity='+searchParams.capacity;
axios.get('/getFilteredOffers' + queryParams)
.then(response => {
dispatch(saveFoundOffers(response.data)); --> saves the state
})
.catch(error => {
console.log(error);
})
}
}
?我只想单击子组件中的“搜索”按钮时才调用此方法。也许我的方法不好?
感谢所有提示!
答案 0 :(得分:1)
问题是props.offersFound(searchCriteria)
每render
被调用。 onSubmit
道具应该是在提交时要调用的函数。目前,它正在立即被调用。
此行:
onSubmit={props.offersFound(searchCriteria)}
应该(或类似):
onSubmit={() => props.offersFound(searchCriteria)}
当前,在brand
(或capacity
)字段中键入时,将调用handleBrand
更改回调。这将调用setSearchCriteria
(状态更新),从而触发组件的重新呈现。重新渲染此组件时,它会立即调用props.offersFound(searchCriteria)
并将返回值传递给onSubmit
道具。您可能希望onSubmit
属性是提交时要调用的函数。
有关更多详情,请参见documentation for controlled components。
答案 1 :(得分:1)
<form
noValidate
autoComplete="off"
onSubmit={props.offersFound(searchCriteria)}>
您将立即调用prop并尝试使用返回的结果作为事件侦听器。应该是
<form
noValidate
autoComplete="off"
onSubmit={() => props.offersFound(searchCriteria)}>
代替