0

I have some nested state in class component that I want change it to functional component, but I don't know how can I use nested state in functional component with hook and useState and also useEffect? can you help me please?

state = {
  products: null,
  totalPrice: 0,
  addCounter: 0,
  purchased: false,
  loading: false,
  form: {
    name: {
      elementType: 'input',
      elmentConfig: {
        type: 'text',
        palceholder: 'Name...',
      },
      value: '',
      validation: {
        required: true,
      },
      valid: false,
      used: false,
    },
    password: {
      elementType: 'input',
      elmentConfig: {
        type: 'password',
        palceholder: 'Password...',
      },
      value: '',
      validation: {
        required: true,
      },
      valid: false,
      used: false,
    },
    email: {
      elementType: 'input',
      elmentConfig: {
        type: 'text',
        palceholder: 'Email...',
      },
      value: '',
      validation: {
        required: true,
      },
      valid: false,
      used: false,
    },
  },
};
Parisa
  • 49
  • 6

2 Answers2

1

Convert your state with useState, however I would recommend separating your state in smaller 'states' to make it a little more manageable and not have deeply nested values.

eg.

const [checkout, setCheckout] = useState({
    products: null,
    totalPrice: 0,
    addCounter: 0,
    purchased: false,
    loading: false
});

const [userForm, setUserForm] = useState({
    name: {
        elementType: 'input',
        elementConfig: {
           type: 'text',
           placeholder: 'Name...'
        },
        value: '',
        validation: {
            required: true
        },
        valid: false,
        used: false,
    },
    password: {
        elementType: 'input',
        elementConfig: {
            type: 'password',
            placeholder: 'Password...'
        },
        value: '',
        validation: {
            required: true
        },
        valid: false,
        used: false,
    },
    email: {
        elementType: 'input',
        elementConfig: {
            type: 'text',
            palceholder: 'Email...'
        },
        value: '',
        validation: {
            required: true
        },
        valid: false,
        used: false,
    }
});

nb. you can get your state from the useState hook simply by calling the state name once it has been initialised.

setting your state can become complex when working with deeply nested states so the 'shallower' the better for each state imho.

see documentation here: https://reactjs.org/docs/hooks-state.html with equivalent class examples

Iamspencr
  • 11
  • 3
  • thank you, then how can i use them for changing state? for eg. I want change state of required? how can I do that then? – Parisa Nov 19 '20 at 06:06
  • I'd refer you to this stack response: https://stackoverflow.com/questions/57798841/react-setting-state-for-deeply-nested-objects-w-hooks articulated much better than i could :) – Iamspencr Nov 23 '20 at 14:27
0

You can try:

const [formElements, setFormElements] = useState({
  products: null,
  totalPrice: 0,
  addCounter: 0,
  purchased: false,
  loading: false,
  form: {
    name: {
      elementType: 'input',
      elmentConfig: {
        type: 'text',
        palceholder: 'Name...',
      },
      value: '',
      validation: {
        required: true,
      },
      valid: false,
      used: false,
    },
    password: {
      elementType: 'input',
      elmentConfig: {
        type: 'password',
        palceholder: 'Password...',
      },
      value: '',
      validation: {
        required: true,
      },
      valid: false,
      used: false,
    },
    email: {
      elementType: 'input',
      elmentConfig: {
        type: 'text',
        palceholder: 'Email...',
      },
      value: '',
      validation: {
        required: true,
      },
      valid: false,
      used: false,
    },
  },
});

By using this, the initial state can be available in formElements and to update it you can use setFormElements function.

Reference

Mayank Pandeyz
  • 25,704
  • 4
  • 40
  • 59