React-如何将自定义函数从子组件发送到父组件

时间:2019-10-25 15:00:25

标签: reactjs react-hooks

我正在创建自定义步骤向导,请在下面找到实现:

export const Wizard: React.FC<Props> = props => {
const {
    steps,
    startAtStep = 0,
    showStepsNavigation = true,
    prevButtonText = 'Back',
    nextButtonText = 'Next',
    onStepChange,
    nextButtonTextOnFinalStep,
    onNextClicked,
    onPreviousClicked
} = props;
const [currentStep, setCurrentStep] = useState(startAtStep);

let CurrentStepComponent = steps[currentStep].Component;

const nextStep = () => {
    setCurrentStep(currentStep + 1);
};

const previousStep = () => {
    setCurrentStep(currentStep - 1);
};

const goToStep = (stepId: number) => {
    const stepIndex = steps.findIndex(step => step.id == stepId);
    if (stepIndex != -1) {
        setCurrentStep(stepIndex);
    }
};

const handlePreviousClick = () => {
    if (onPreviousClicked && typeof onPreviousClicked == 'function') {
        onPreviousClicked();
    }

    previousStep();
};

const handleNextClick = () => {
    if (onNextClicked && typeof onNextClicked == 'function') {
        onNextClicked();
    }

    nextStep();
};

return (
    <article>
        <section>
            <CurrentStepComponent {...props} goToStep={goToStep} nextStep={nextStep} previousStep={previousStep} />
        </section>
        <footer>
            <div className="wizard-buttons-container back-buttons">
                <Button
                    className="wizard-button wizard-button--back"
                    secondary
                    onClick={handlePreviousClick}
                    disabled={steps[currentStep - 1] == null}
                >
                    <i className="fas fa-chevron-left"></i>
                    {prevButtonText}
                </Button>
            </div>

            <div className="wizard-buttons-container next-buttons">
                <Button
                    className="wizard-button wizard-button--next"
                    onClick={handleNextClick}
                    disabled={steps[currentStep + 1] == null}
                >
                    {steps[currentStep + 1] == null && nextButtonTextOnFinalStep ? nextButtonTextOnFinalStep : nextButtonText}
                    <i className="fas fa-chevron-right"></i>
                </Button>
            </div>
        </footer>
    </article>
);

};

我的使用方式如下:

    const steps = [
    {
        id: 1,
        label: 'Directors and Owners',
        Component: DirectorsAndOwnersStep
    },
    {
        id: 2,
        label: 'Bank Account',
        Component: BankAccountStep
    },
    {
        id: 3,
        label: 'Company Documents',
        Component: CompanyDocumentsStep
    },
    {
        id: 4,
        label: 'Review and Submit',
        Component: ReviewAndSubmitStep
    }
];

type Props = RouteComponentProps<MatchParams>;

export const EnterpriseOnboardingPage: React.FC<Props> = () => {

    const onNext = () => {
        console.log('Next Clicked');
    };

    const onPrevious = () => {
        console.log('Previous Clicked');
    };

    return (
        <section>
            <Wizard
                steps={steps}
                nextButtonTextOnFinalStep="Submit"
                onNextClicked={onNext}
                onPreviousClicked={onPrevious}
            />
        </section>
    );
};

现在这是我的问题,在子组件中,我想处理用户单击“下一步”时应该发生的情况,类似onNextClick之类的事情在子组件中执行此自定义功能,而不是执行向导组件中实现的默认行为。 / p>

我尝试在向导“ nextClbRegistered”中设置状态,并通过将“ setNextClbRegistered”发送给子代以传递自定义函数并执行它,然后在向导中的“ handleNextClick”中是否有一个函数定义执行它。但它始终是不确定的。

任何想法是最好的方法吗?

预先感谢!

1 个答案:

答案 0 :(得分:3)

反应全部是有关在组件树中向下流动的数据的。如果您希望Child能够显示和/或修改ChildParent之间的共享状态,则应lift your state up并通过props传递给它到children

const Parent = () =>{
    const [title, settitle] = useState('foo')

    return <Child title={title} setTitle={setTitle} />
}


const Child = ({ title, setTitle}) =>{
     return <input value={title} onChange={e => setTitle(e.target.value)} />
}

基于类的组件

class Parent extends React.Component{
    state = { title: '' }

    setTitle = title => this.setState({ title })

    render(){
        const { title } = this.state
        return <Child title={title} setTitle={this.setTitle} />
    }
}


class Child extends React.Component{
    render(){
        const { title, setTitle } = this.props
        return <input value={value} setTitle={e => setTitle(e.target.value)} />
    }
}