与Redux反应-回调函数被意外调用

时间:2019-09-29 22:06:59

标签: reactjs react-redux

我还不是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); }) } } ?我只想单击子组件中的“搜索”按钮时才调用此方法。也许我的方法不好?

感谢所有提示!

2 个答案:

答案 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)}>

代替

相关问题