简体   繁体   中英

How i can save state ( data ) on Previous/Back" button click in ReactJS

I am new to reactjs, I am working on Wizard form, i want to save user data. For example When user input data to their field and click on next button if user click on previous button to edit data i want to not lost user data. I did't have much knowledge in reactjs how it would be possible . Could you please help me? I will also share my Wizard Form code where i control further 4 steps

Code

import React from 'react';
import 'antd/dist/antd.css';
import './WizarStyle.css';
import styled from 'styled-components';
import { Steps, Form, Button, Card } from 'antd';
import RegisterStepOne from '../RegisterStepOne/RegisterStepOne';
import RegisterStepTwo from '../RegisterStepTwo/RegisterStepTwo';
import RegisterStepThree from '../RegisterStepThree/RegisterStepThree';
import RegisterStepFour from '../RegisterStepFour/RegisterStepFour';
import Success from '../Successful/Success';
const Step = Steps.Step;
const GeneralText = styled.div`
  color: red;
  font-size: 26px;
  font-weight: 600;
  text-align: center;
  padding-bottom: 30px;
  font-family: Lato;
  margin-top: 50px;
  color: #012653;
`;
const ButtonWrapper = styled.div`
  text-align: center;
  margin-top: 26px;
`;
class Wizard extends React.Component {
  constructor(props) {
    super(props);
    // this.modifier = null;
    this.state = {
      current: 0,
      // user: null,
    };
  }

  steps = [
    {
      title: 'General Information',
      content: (
        <RegisterStepOne
          getFieldDecorator={this.props.form.getFieldDecorator}
        />
      ),
    },
    {
      title: 'Upload Photo',
      content: (
        <RegisterStepTwo
          getFieldDecorator={this.props.form.getFieldDecorator}
        />
      ),
    },
    {
      title: 'Upload Resume',
      content: (
        <RegisterStepThree
          getFieldDecorator={this.props.form.getFieldDecorator}
        />
      ),
    },
    {
      title: 'Add Skills',
      content: (
        <RegisterStepFour
          getFieldDecorator={this.props.form.getFieldDecorator}
        />
      ),
    },
  ];

  next() {
    this.setState(prevState => ({ current: prevState.current + 1 }));
  }

  handlechanges=input=>e=>{
    this.setState({[input]:e.target.value})
  }
  handleSubmit = e => {
    e.preventDefault();
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (!err) {
        // this.setState({ user: [this.state.user, values] });
        const userOject = {
          profile: {
            type: 'employee',
            screen: 'Step0',
          },
          ...values,
        };

        if (this.state.current === 0 && this.state.current <= 3) {
          fetch('http://138.197.207.41:9000/api/auth/createuser', {
            method: 'POST',
            headers: {
              Accept: 'application/json',
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              user: userOject,
            }),
          })
            .then(response => response.json())
            .then(user => {
              if (user.error) {
                console.warn(user);
              } else if (user && user.user) {
                console.warn(user);
                localStorage.setItem('user', JSON.stringify(user.user));
                const modifier = {
                  id: user.user._id,
                  type: user.user.profile.type,
                  profile: {
                    fullName: values.fullName,
                    position: values.lastPosition,
                    username: values.username,
                    location: values.lastPosition,
                    company: values.lastCompany,
                    password: values.password,
                    photo: '',
                    screen: 'Step1',
                  },
                };
                fetch(`http://138.197.207.41:9000/api/auth/user/update`, {
                  method: 'POST',
                  headers: {
                    Accept: 'application/json',
                    'Content-Type': 'application/json',
                  },
                  body: JSON.stringify({
                    id: user.user._id,
                    modifier,
                  }),
                })
                  .then(response => response.json())
                  .then(res => {
                    if (res.error) {
                      console.warn(res);
                    } else {
                      console.warn(res);
                      this.next();
                    }
                  })
                  .done();
              }
            });
        } else {
          const user = JSON.parse(localStorage.getItem('user'));
          fetch(`http://138.197.207.41:9000/api/auth/user/updateskills`, {
            method: 'POST',
            headers: {
              Accept: 'application/json',
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              id: user._id,
              type: user.profile.type,
              modifier: {
                'profile.skills': values.skills,
              },
            }),
          })
            .then(response => response.json())
            .then(res => {
              if (res.error) {
                console.warn(res);
              } else {
                console.warn(res);
                // this.afterDone();
                this.next();
              }
            })
            .done();
        }
      }
    });
  };

  // afterDone() {
  //   <Success getFieldDecorator={this.props.form.getFieldDecorator} />;
  // }

  prev() {
    this.setState(prevState => ({ current: prevState.current - 1 }));
  }

  getStep = props => this.steps[this.state.current].content;

  render() {
    if (this.state.current <= 3) {
      const { current } = this.state;
      const { getFieldDecorator } = this.props.form;
      return (
        <Card style={{ borderRadius: 10 }}>
          <Form onSubmit={this.handleSubmit}>
            <GeneralText>{this.steps[current].title}</GeneralText>
            <Steps current={current}>
              {this.steps.map((item, index) => (
                <Step key={index.toString()} small="small" />
              ))}
            </Steps>
            <div className="steps-content">
              {this.getStep(getFieldDecorator)}
            </div>
            <div className="steps-action">
              {' '}
              <ButtonWrapper>
                {current < this.steps.length - 1 && (
                  <Button
                    type="primary"
                    htmlType="submit"
                    style={{
                      background: '#ff9700',
                      fontWeight: 'bold',
                      border: 'none',
                    }}
                  >
                    Next
                  </Button>
                )}
                {current === this.steps.length - 1 && (
                  <Button
                    type="primary"
                    htmlType="submit"
                    style={{
                      background: '#ff9700',
                      fontWeight: 'bold',
                      border: 'none',
                    }}
                  >
                    Done
                  </Button>
                )}
                {current > 0 && (
                  <Button
                    className="preButton"
                    style={{ marginLeft: 8, border: '1px solid #ff9700' }}
                    onClick={() => this.prev()}
                  >
                    Previous
                  </Button>
                )}
              </ButtonWrapper>
            </div>
          </Form>
        </Card>
      );
    } else {
      return <Success />;
    }
  }
}
export default Form.create()(Wizard);

For this you need to change the default behavior of steps . You can use show/hide functionality by using some css:

.foo {
  display: none;
  opacity: 0;
  animation: fade-out 1s 1;
}
.foo.fade-in {
  display: block;
  opacity: 1;
  animation: fade-in 0.5s 1;
}

And then use condition to add/replace classes in js:

{steps.map(({ title, content }, i) => (
      <div
        key={title}
        className={i === this.state.current ? "foo fade-in" : "foo"}
      >
        {content}
      </div>
))}

I have created a working demo .

See if are not rendering component you can manage old data in local state, if you are then you need store data in some store like redux, selector,

better use each click save your current page data and if user comes previous page just fetch the data form API and show him as editable fields.

and my suggestion use redux store for response data storage and and for ction use saga. it will make you as a smart and rapid developer

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