Реагировать - Как отправить пользовательскую функцию от дочернего к родительскому компоненту - PullRequest
1 голос
/ 25 октября 2019

Я создаю мастер пользовательских шагов, пожалуйста, найдите реализацию ниже:

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>
    );
};

Теперь вот моя проблема, в дочерних компонентах я хочу обработать то, что должно произойти, когда пользователь нажимает Next, что-то вроде onNextClick выполняет эту пользовательскую функцию в дочернем компоненте, а не выполняет поведение по умолчанию, реализованное в компоненте Wizard.

Я пытался установить State в мастере "nextClbRegistered" и через отправку "setNextClbRegistered" дочерним элементам, чтобы передать пользовательскую функцию и выполнить ее, а затем в мастере в "handleNextClick", если естьопределенная функция выполняет его. но оно всегда не определено.

Есть идеи, как лучше всего это сделать?

Заранее спасибо!

1 Ответ

3 голосов
/ 25 октября 2019

React - это все, что касается данных, передаваемых в дереве компонентов. Если вы хотите, чтобы ваш Child мог показывать и / или изменять общее состояние между Child и Parent, вам следует поднять ваше состояние до и передать его через 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)} />
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...