首页 > 解决方案 > 如何在注册流程中管理状态(ReactJS)

问题描述

因此,我正在使用 React/NextJS、AWS Cognito 和 Stripe 构建注册和支付流程。我创建了一个类组件来管理状态和整体流程,子组件处理各个步骤。我遇到的问题是管理状态,以便每个组件都可以访问状态并对其进行更改,以及使用父组件中而不是子组件中的函数。请注意,子组件是功能性的,而不是类。这是一步一步的流程:

父组件

import React, { Component } from "react";
import Layout from "../../components/layouts/mainlayout/mainlayout";
//import { handleSubmit } from "../../components/auth/awshelper";
import { Auth } from "aws-amplify";
import FlowStep1 from "../../components/auth/clubflow/step1";
import FlowStep2 from "../../components/auth/clubflow/step2";
import FlowStep3 from "../../components/auth/clubflow/step3";
//import { Router } from "next/router";

const meta = {
  title: "Join the club!",
  description: "Sign up and enjoy the best travel experiences ever."
};

class ClubFlow extends Component {
  state = {
    firstname: "",
    lastname: "",
    username: "",
    phonenumber: "",
    password: "",
    confirmpassword: "",
    step: 1,
    go: false,
    plan: null,
    member: false,
    errors: {
      cognito: null,
      blankfield: false,
      passwordmatch: false
    }
  };
  /*Unnecessary functions:
  getStripeFunc = func => {
    return func;
  };
  */
  clearErrorState = () => {
    this.setState({
      errors: {
        cognito: null,
        blankfield: false,
        passwordmatch: false
      }
    });
  };
  choosePlan = e => {
    setState({ plan: e.target.value });
  };
  onInputChange = event => {
    //const [firstname, setFirstname] = useState("");
    this.setState({
      [event.target.id]: event.target.value
    });
    document.getElementById(event.target.id).classList.remove("is-danger");
  };

  handleSubmit = async event => {
    event.preventDefault();
    // Form validation
    this.clearErrorState();
    const error = null; /*Validate(event, this.state)*/
    if (error) {
      console.log("an validation erreor was fired");
      this.setState({
        errors: { ...this.state.errors, ...error }
      });
    }

    // AWS Cognito integration here
    const { firstname, lastname, phonenumber, username, password } = this.state;
    try {
      const signUpResponse = await Auth.signUp({
        username,
        password,
        attributes: {
          name: firstname,
          family_name: lastname,
          phone_number: phonenumber
        }
      });

      if (signUpResponse) {
        this.setState({ step: 2, go: true });
      }
    } catch (error) {
      let err = null;
      !error.message ? (err = { message: error }) : (err = error);
      this.setState({
        errors: { ...this.state.errors, cognito: error }
      });
    }
  };

  //This function sets which plan the user selects. Eventually this value will be passed down to the checkout form as a prop.
  goNext = async () => {
    try {
      if (this.state.step === 1) {
        this.handleSubmit(event);

        if (
          this.state.step <
          3 /*&&
          this
            .signUpResponse /*Remove the previous comment in order for the next button to work correctly.*/
        ) {
          this.setState(state => ({
            step: state.step + 1
          }));
        }
      } else if (this.state.step === 2) {
        this.setState(state => ({
          step: state.step + 1
        }));
      } else {
        this.getStripeFunc();
      }
    } catch (error) {
      console.log("You have a problem");
    }
  };

  goBack = () => {
    if (this.state.step > 1) {
      this.setState(state => ({
        step: state.step - 1
      }));
    }
  };

  render() {
    let stage;
    if (this.state.step === 1) {
      stage = (
        <FlowStep1 state={this.state} onInputChange={this.onInputChange} />
      );
    } else if (this.state.step === 2) {
      stage = <FlowStep2 state={this.state} choosePlan={this.choosePlan} />;
    } else {
      stage = <FlowStep3 state={this.state} />;
    }
    //console.log(this.state.plan);
    return (
      <Layout class={"ovh"} meta={meta}>
  1. 用户可以通过输入他们的姓名、电子邮件、电话和密码来注册和创建帐户。
import FormErrors from "../FormErrors";
import { Auth } from "aws-amplify";
import React, { Component } from "react";

/*import {
  backspacerUP,
  backspacerDOWN
} from "../../utilities/phonenumbervalidator";
const onKeyUp = backspacerUP;
const onKeyDown = backspacerDOWN;
Might need to use a plugin: https://www.npmjs.com/package/react-phone-input-auto-format*/

class FlowStep1 extends Component {
  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {
    return (
      <section className="section auth">
        <div className="container">
          <h1>Register</h1>
          <FormErrors /*formerrors={state.errors}*/ />

  1. 用户可以选择需要将用户选择的计划传递到步骤 3 的计划:
import React, { useState } from "react";

const FlowStep2 = (props) => {
  const plan
  const [plan, setPlan] = useState(0);
  return (
    <div className="mb-4">
      <h2>this is what is in state:{plan}</h2>
      <input
        type="radio"
        name="plan"
        value="1"
        readOnly
        //checked={this.state.plan === 1}
        onChange={() => setPlan(1)}
      />
      <input
        type="radio"
        name="plan"
        value="2"
        readOnly
        onChange={() => setPlan(2)}
        className="ml-3"
      />
      <input
        type="radio"
        name="plan"
        value="3"
        //checked={true}
        onChange={() => setPlan(3)}
        className="ml-3"
      />
    </div>
  );
};

export default FlowStep2;
  1. 用户可以输入他们的信用卡信息并提交。一旦按条收费并根据用户在第二步中选择的计划收费,他们将收到一封确认电子邮件,并将被导航到欢迎页面。选择的计划最终将需要传递到一个快速服务器,该服务器将处理费用并将其传递给条带以根据他们选择的计划处理计费。
import ClubPayWrap from "../../payments/clubpaywrap";
const FlowStep3 = props => {
  return (
    <div>
      <h2>Payment</h2>
      <ClubPayWrap flowstate={props.state} />
    </div>
  );
};
export default FlowStep3;

请让我知道是否需要提供更多详细信息。

标签: reactjsstripe-paymentsamazon-cognito

解决方案


为了在基于反应的应用程序中管理状态,有不同的方法。您需要将logged in用户数据存储在一个global store您可以在不同的路由和组件中访问的地方。

  1. 反应最常用的 store manager 是Redux。在最新版本中,它提供了一些钩子。redux 钩子使访问您的商店变得如此容易。

  2. 下一个是mobX。我个人还没有使用它,我无法帮助你!

  3. 另一种是自己提供的Context Apireact。React 添加了一些钩子以使其易于使用。

  4. 在 React 中提供了另一种用于管理状态的技术,称为Rxjs,它有点不同,可能不适合您的情况。

最后,我认为第一个是您的完美解决方案,然后是第三个。


推荐阅读