简体   繁体   中英

Can't call client methods from the parent in React?

I have a basic React App that looks like this:

App = createClass({
    update(text){
        this.setState({params: make_params(text)})
    }
    componentWillMount() {
        this.updatePeriodic = _.throttle(this.update, 500)
    }
    render() {
        return <div>
            <SearchField cb={this.updatePeridic}/>
            <ListOfThings searchParams={this.state.params}/>
        </div>;
    }
};

Which is working great. I'm now trying to add a reset button:

App = createClass({
    update(text){
        this.setState({params: make_params(text)})
    }
    componentWillMount() {
        this.updatePeriodic = _.throttle(this.update, 500)
    }
    render() {
        search = <SearchField cb={this.updatePeridic}/>
        const reset = () => {
            search.reset()
            this.update("")
        }
        return <div>
            {search}
            <button onClick={reset} />
            <ListOfThings searchParams={this.state.params} />
        </div>;
    }
};

Except I'm getting an error when I try to call search.reset , saying that that function doesn't exist. I'm not really sure what else to do– I know that it's sort of gauche to have parents call the setState of their children, but I didn't see any other way to accomplish this; I don't want to do this:

<SearchField value={this.state.text} cb={this.setState({text: ""})}/>

Because, A) that will result in a rerender of the WHOLE APP every time someone types in that field, and B) when the raw text is part of the App state, there's no obvious way to throttle the params updates to the child ListOfThings. Thoughts?

You cannot call child methods from your parent.
What you can do:

  • put a parameter in parent state,
  • pass that as a prop to the child,
  • make the child respond to the reset parameter.

Something like this:

update(text, shouldResetChild){
  this.setState({
    params: make_params(text), 
    shouldResetChild: shouldResetChild        // store action to reset child
  })
}

And in your render:

search = <SearchField 
            cb={this.updatePeridic}
            shouldReset = {this.state.shouldResetChild} />    // pass to child
const reset = () => {
  this.update("", true)
}

And in your child somewhere (which lifecycle method depends on what reset() does).

if (this.props.shouldReset) {
  this.reset()
}

PS: In any other setState() calls inside your parent (in your example there were none), you should include the { shouldResetChild : false } to reset the parameter in state, to make sure that reset happens only once/ only when reset button is clicked.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM