Как императивно назначить реквизит компоненту React?

Как мне обязательно добавить свойство к компоненту (без использования тега компонента?)

Когда я пытаюсь это:

component.props.onChange = onChange;

Я получаю следующую ошибку.

TypeError: Cannot assign to read only property 'onChange' of object '#'

Вот еще немного моего кода для контекста.

FormTemplate.js
const getComponent = ( onChange, component, ) => {
  component.props.onChange = onChange; // this line throws the error
  return component;
}

const FormTemplate = ({ fields, onChange, }) => {
  // ...
  return (
    <div>
      {
        fields.map( ({ component, ...rest, }) =>
          ( component && (rest.type === 'component') )
          ?
          getComponent(onChange, component,)
          :
          getTextField(onChange, rest,)
        )
      }
    </div>
  );
}
AppConfig.js
const formFieldConfig = {
  zip: {
    type: 'component',
    label: 'Zip code',
    icon: 'place',
    component: <ZipCodeInput />,
  }, 
}
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
134
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Как говорится в ошибке, вы не можете изменять реквизиты, которые получаете напрямую. Единственный способ обновить свойства компонента — клонировать элемент и добавить/обновить свойства клонированного элемента.

const getComponent = ( onChange, component, ) =>
  React.cloneElement(component, { onChange })

Есть еще один способ подойти к этому, который сохранит ваш код в контексте компонентов (вместо создания вспомогательной функции getComponent, которая добавляет некоторую косвенность) и, вероятно, будет более понятным для других разработчиков, работающих с этим кодом в будущем:

const formFieldConfig = {
  zip: {
    type: 'component',
    label: 'Zip code',
    icon: 'place',
    component: ZipCodeInput, // <-- Don't create an element yet
  }, 
}

const FormTemplate = ({ fields, onChange, }) => {
  // ...
  return (
    <div>
      {
        fields.map(({ component, ...rest, }) => {
          const Component = (component && (rest.type === 'component'))
            ? component
            : textField // <-- Assuming this is also a React component

          return <Component onChange = {onChange} {...rest} />
        })
      }
    </div>
  );
}

Трудно сказать наверняка, что это будет работать с TextField, не видя кода, но не должно быть сложно заставить его работать и с getTextField.

Другие вопросы по теме