2
\$\begingroup\$

I have a nested state which is needed to set its state by a key's value:

state = {
    income_source: {
        type: 'text', label_name: 'Income Source', value: '', helper: 'dropdown',
    },
    employment_status: {
        type: 'text', label_name: 'Employment Status', value: '', helper: 'dropdown',
    },

...

I'm getting a huge list from a get_financial_assessment object and the code becomes messy when I tried to setState in componentDidMount():

async componentDidMount() {
    let { get_financial_assessment } = await DAO.getFinancialAssessment()
    if( get_financial_assessment ) {
        const {
            account_turnover,
            cfd_score,
            education_level,
            employment_industry,
            employment_status,
            estimated_worth,
            financial_information_score,
            income_source,
            net_income,
            occupation,
            source_of_wealth,
            total_score,
            trading_score,
        } = get_financial_assessment;

        this.setState(prevState => ({
            anticipated_account_turnover: {...prevState.anticipated_account_turnover, value: account_turnover},
            occupation: {...prevState.occupation, value: cfd_score},
            level_of_education: {...prevState.level_of_education, value: education_level},
            source_of_wealth: {...prevState.source_of_wealth, value: employment_industry},
            net_annual_income: {...prevState.net_annual_income, value: employment_status},
            estimated_net_worth: {...prevState.estimated_net_worth, value: estimated_worth},
            source_of_wealth: {...prevState.source_of_wealth, value: financial_information_score},
        }));
    } else {
        console.log('nope');
    }
}

Any better way? One possible approach might be, once we get the data, we can make an object and setState the object to the state. Would it be the best possible answer?

\$\endgroup\$
1
\$\begingroup\$

First things first, I am against using different names in things that are inherently the same. If you do not have any other option, you could the data coming from the DAO as soon as they are fetched from the server.

If that is not an option, since this code is indeed messy, I would move this logic into a function while indicating the mapping from one state to the other (this is similar to what Redux does with mapStateToProps).

const mapFinancialAssesmentToState = (fa, state) => {
  const mapping = {
    anticipated_account_turnover: fa.account_turnover,
    occupation: fa.cfd_score
    //...
  };
  const nextState = {};
  Object.keys(mapping).forEach(key => {
    nextState[key] = { ...state[key], value: mapping[key] };
  })
  return nextState;
}

async componentDidMount() {
  let { get_financial_assessment } = await DAO.getFinancialAssessment();
  if (get_financial_assessment) {
      this.setState(mapFinancialAssesmentToState(get_financial_assessment, this.state))
  } else {
    console.log('nope');
  }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.