Обновлять определенные свойства в конкретном объекте

#javascript #reactjs

#javascript #reactjs

Вопрос:

Я просто немного зацикливаюсь на довольно простой задаче. Заранее приношу извинения, если на этот вопрос уже дан ответ. Я просто не могу его найти. Я получил объекты в состоянии

     state = {
    controls: {
        email: {
            elementConfig: {
                type: 'email'
            },
            placeholder: 'Email Address',
            value: '',
            validation: {
                required: true,
                isEmail: true
            },
            valid: false,
            touched: false,
            errorMsg: ""
        },
        password: {
            elementConfig: {
                type: 'password'
            },
            placeholder: 'Password',
            value: '',
            validation: {
                required: true,
                minLength: 6
            },
            valid: false,
            touched: false,
            errorMsg: ""
        }
    },
};
  

и мне нужно обновить «touched» до true и «ErrorMsg» до текста, только если «valid» в объекте равно false

Мне удалось отфильтровать все ключи объекта с «допустимым» значением, равным false

 const invalidInputs = Object.keys(this.state.controls).filter(key => {
        return this.state.controls[key].valid === false
      })
  

Теперь мне нужно перебрать все «invalidInputs» и обновить задетые значения до true и «ErrorMsg» для определенного текста. Я пытался

   for (let key in invalidInputs){
        const updatedControl = {
            ...this.state.controls,
            [invalidInputs[key]]: {
                ...this.state.controls[invalidInputs[key]],
                touched: true,
                errorMsg: errorMsg(this.state.controls[invalidInputs[key]].validation, this.state.controls[invalidInputs[key]].value)
            }
        };
        this.setState({controls:updatedControl})
        console.log(updatedControl)
      }
  

но это, очевидно, не работает. Кто-нибудь может дать мне какое-нибудь хорошее решение или направить меня к ответу?

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

Комментарии:

1. Вы хотите, чтобы в результате всего было отфильтровано только controls after?

2. Нет, я хотел обновить свойства в состоянии

Ответ №1:

Используется for..in для перебора объекта и проверки значения valid

 let state = {
  controls: {
    email: {
      elementConfig: {
        type: 'email'
      },
      placeholder: 'Email Address',
      value: '',
      validation: {
        required: true,
        isEmail: true
      },
      valid: false,
      touched: false,
      errorMsg: ""
    },
    password: {
      elementConfig: {
        type: 'password'
      },
      placeholder: 'Password',
      value: '',
      validation: {
        required: true,
        minLength: 6
      },
      valid: false,
      touched: false,
      errorMsg: ""
    }
  },
};

for (let keys in state.controls) {
  if (!state.controls[keys].valid) {
    state.controls[keys].errorMsg = 'New Msg';
    state.controls[keys].touched = true;
  }
}

console.log(state)  

Комментарии:

1. Спасибо, чувак… Это то, что мне было нужно, и я не понимаю, где я потерялся. Еще раз спасибо

Ответ №2:

Вы можете использовать map() и изменять объект в соответствии с потребностями вместо использования filter() .

 let state = {
    controls: {
        email: {
            elementConfig: {
                type: 'email'
            },
            placeholder: 'Email Address',
            value: '',
            validation: {
                required: true,
                isEmail: true
            },
            valid: false,
            touched: false,
            errorMsg: ""
        },
        password: {
            elementConfig: {
                type: 'password'
            },
            placeholder: 'Password',
            value: '',
            validation: {
                required: true,
                minLength: 6
            },
            valid: false,
            touched: false,
            errorMsg: ""
        }
    },
};
let result = Object.keys(state.controls)
                   .map((con) => (!state.controls[con].valid ?
                   ({...state.controls[con],errorMsg:"New msg",touched:true}) :
                   ({...state.controls[con],touched:true})))
console.log(result);  

Комментарии:

1. Также спасибо Махир Али за это решение… Но первое решение более приличное.

2. @ptr.chov да, это так. Но будьте осторожны, это приведет к изменению исходного объекта

3. Да, в частности, в React желательно неизменяемое состояние

4. Привет @Maheer Ali, я пробовал по-вашему, но, к сожалению, переменная «result» возвращает массив объектов, которые затем, когда я обновляю состояние с помощью setState({controls:result}), преобразуют исходные объекты в массив. Есть ли какой-нибудь другой способ сделать это?

5. @ptr.chov Почему ты не используешь метод brk?

Ответ №3:

Я просто хотел опубликовать решение, которое работает для меня, которое совпадает с первым решением, но без изменяющегося состояния

 const updatedControls = { ...this.state.controls }

    for (let keys in updatedControls) {
        if (updatedControls[keys].valid === false) {
            const control = updatedControls[keys]
            control.errorMsg = "new msg"
            control.touched = true

            updatedControls[keys] = control
        }
    }
    this.setState({ controls: updatedControls })