简体   繁体   English

在父组件中调用 function 而不使用 props

[英]Call function in parent component without using props

I have a an App component that renders a CustomerForm component like so:我有一个 App 组件,它呈现一个CustomerForm组件,如下所示:

App.js应用程序.js

class App extends Component{
    constructor(props){
        this.state = {logged_in: true};

    }

    logout = () => {
      this.setState({logged_in: false}):
    }
    render(){
        return(
            <div>
                <CustomerForm />
            </div>
        )
    }
}

In my CustomerForm component, I have an onSubmit function that is called when the form submits:在我的CustomerForm组件中,我有一个在表单提交时调用的onSubmit function:

CustomerForm.js CustomerForm.js

class CustomerForm extends Component{
    
    constructor(props){
         this.state = { submitting: false }
    }

    handleSubmit = (e) => {
       e.preventDefault();
       this.setState({submitting: true});
       try{
           //API CALL HERE
       }catch(e){
           //if error == unauthorized, then logout. 
       }

    }
}

When I render the CustomerForm component from the App component, I realize that I could pass a reference to logout via a prop, however, my application is much larger than the one I have provided here.当我从App组件渲染CustomerForm组件时,我意识到我可以通过道具传递对logout的引用,但是,我的应用程序比我在此处提供的应用程序大得多。 Ultimately, I want to be able to call the logout() function that is in the App component from either like a helper file or any nested component (preferably a helper file).最终,我希望能够从帮助文件或任何嵌套组件(最好是帮助文件)中调用App组件中的logout() function。 Once this function is called, the state for the App component would be updated to reflect that the user is now logged out.调用此 function 后, App组件的 state 将更新以反映用户现在已注销。 I tried to use createContext and this allowed me to pass the attributes and functions I needed, however the functions were only available in the JSX like so:我尝试使用createContext ,这允许我传递我需要的属性和函数,但是这些函数仅在 JSX 中可用,如下所示:

<authContext.Consumer>
    {({logout}) => {
      return (
    
        <Form onSubmit={logout}/>
      );
    }}
</authContext.Consumer> 

However, I need to be able to access logout from within the handleSubmit function.但是,我需要能够从handleSubmit function 中访问logout I know that I can pass the logout function as a reference to handleSubmit, but I figure there is a cleaner way to do this.我知道我可以通过logout function 作为对 handleSubmit 的引用,但我认为有一种更简洁的方法可以做到这一点。

With Context api and HOC , you can do that.使用Context apiHOC ,您可以做到这一点。 let me know your thought.让我知道你的想法。

app.js应用程序.js

/ Create a new context for the app
export const AppContext = React.createContext('app');

class App extends Component{
    constructor(props){
        this.state = {logged_in: true};
    }

    logout = () => {
      this.setState({logged_in: false}):
    }
    render(){
        return(
            <AppContext.Provider
                value={{
                    state: this.state,
                    logout: this.logout
                }}
            >
                <CustomerForm />
            </AppContext.Provider>
        )
    }
}

Create a HOC for your Context为你的上下文创建一个 HOC

withAppContext.js withAppContext.js

import {AppContext} from './app.js'

export function withAppContext(Component) {
    return function WrapperComponent(props) {
        return (
            <AppContext.Consumer>
                {state => <Component {...props} context={state} />}
            </AppContext.Consumer>
        );
    };
}

CustomerForm.js CustomerForm.js

import { withAppContext } from 'withAppContext.js'

class CustomerForm extends Component{
    
    constructor(props){
         this.state = { submitting: false }
    }

    handleSubmit = (e) => {
       this.props.context.logout();
    }

  render() {
    return (
      <>
        <div>Child</div>
        <button onClick={this.handleSubmit}>logout</button>
      </>
    );
  }

}

export default withAppContext(CustomerForm); 

codesandbox demo代码沙盒演示

As I understood, you need to use context in both parent component and child component, by using content in the parent component, you will define your parent component's states not internally but in content to use and also by using in child component(s) to change that data.据我了解,您需要在父组件和子组件中使用上下文,通过使用父组件中的内容,您将定义父组件的状态,而不是在内部,而是在要使用的内容中以及通过在子组件中使用来更改该数据。

But, for getting able to do this, you need to change your component to a functional component to get able to use useContent() hook which is just available in functional components.但是,为了能够做到这一点,您需要将组件更改为功能组件,以便能够使用仅在功能组件中可用的 useContent() 挂钩。

for more information, check here: https://reactjs.org/docs/hooks-reference.html#usecontext有关更多信息,请在此处查看: https://reactjs.org/docs/hooks-reference.html#usecontext

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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