Неизменяемое нарушение: текстовые строки должны отображаться в компоненте <Text>

Я обновился с RN 0.54 до 0.57, и мое приложение сильно упало из-за использования React Native Elements.

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

Неизменяемое нарушение: текстовые строки должны отображаться в компоненте &lt;Text&gt;

Итак, я удалил этот код, и ошибка исчезла, однако проблема все еще возникает при запуске этого кода:

{ this.state.event.cards[i].fields[j].error && 

  <Text style = {{ color: '#e74c3c', fontSize: 14, paddingLeft: 5 }}>
    {this.state.event.cards[i].fields[j].error}
  </Text>
}

Когда я начинаю вводить текст, в моем сообщении об ошибке устанавливается пустая строка, поэтому, если возвращается ошибка, ввод в поле заставит ошибку исчезнуть.

Как только this.state.event.cards[i].fields[j].error превращается в строку, мне возвращается эта ошибка. Однако вы можете видеть, что я проверяю, существует ли ошибка, затем я просто отображаю ошибку или, по крайней мере, пытаюсь это сделать.

Другая пара глаз была бы признательна за это.

Убедитесь, что ваш JSX не содержит ошибок и вы случайно не добавили неожиданный текст.

illusionist 08.06.2021 03:44
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
92
1
96 221
30
Перейти к ответу Данный вопрос помечен как решенный

Ответы 30

Обычно это происходит, когда вы выполняете встроенный условный рендеринг. Вы должны удалить пробелы между Text и вашим состоянием, как показано ниже.

{ this.state.event.cards[i].fields[j].error && <Text style = {{ color: '#e74c3c', fontSize: 14, paddingLeft: 5 }}>
    {this.state.event.cards[i].fields[j].error}
  </Text>
}

У меня все написано в одной строке, без пробелов, поскольку я читаю пробелы, которые могут вызвать эту проблему. После изменения на ваш ответ я все еще был встречен с ответом, к сожалению, в этом случае он не сработал. // edit: я разместил его здесь, чтобы его можно было лучше прочитать, извиняюсь за путаницу.

user5283119 17.09.2018 15:18

Я поставил его на суть для вас.

user5283119 17.09.2018 15:21

Ничего плохого не заметил. Какое у вас значение поля error?

Melih Mucuk 17.09.2018 15:33
error не определен до тех пор, пока не произойдет ошибка или вы не начнете вводить это поле, после того как вы введете это поле, оно станет строкой. Мне удалось решить эту проблему, заменив this.state.event.cards[i].fields[j].error на typeof this.state.event.cards[i].fields[j].error === 'string' && this.blah.blah.length > 0 && <Text>stuff here</Text>.
user5283119 17.09.2018 15:43

Иногда из-за точки с запятой также возникает ошибка выброса. В моем случае у меня точка с запятой бросает то же самое. Я удалил это решение.

aviboy2006 11.10.2019 11:48

Также происходит, когда у вас есть / * Комментарии * / в вашей функции return ().

Согласитесь, я потратил 3 дня на отладку из-за комментария к функции рендеринга.

Black Kinght 03.06.2019 03:09

Я тоже, я провожу день за отладкой, и это были закомментированные строки в моей функции рендеринга

Haithem Rihane 21.06.2019 13:50

@ Tare.great catch.Спасибо

Vision Coderz 27.09.2019 06:52

Брооо, хорошо, что я нашел это Исправление, потратив всего 2 часа. TY

yesIamFaded 28.11.2019 13:59

не стоит ли их там использовать, как тогда я могу комментировать? Я использую {/ * любой комментарий * /}, есть ли лучший подход?

GD- Ganesh Deshmukh 11.06.2020 14:51

Для меня это был однострочный комментарий в функции возврата.

jking 15.08.2020 16:23
Ответ принят как подходящий

Для меня следующий код работает нормально, если this.state.error === undefined или это не пустая строка.

render() {
  return (
    <View>
      {this.state.error &&

        <Text>
          Error message: {this.state.error}
        </Text>
      }
    </View>
  );
}

Если состояние ошибки изменится на пустую строку '', у вас будет вышеупомянутое исключение: Invariant Violation: Text strings must be rendered within a <Text> component

Причина этого в том, что при this.state.error === '' следующее выражение будет оцениваться как пустая строка, т.е. '', и это приведет к тому, что Invariant Violation: Text strings must be rendered within a <Text> component

{this.state.error &&

  <Text>
    Error message: {this.state.error}
  </Text>
}

Когда this.state.error === undefined, выражение будет оценено как undefined, чего мы и ожидали, и это нормально.

Это действительно отличное объяснение, спасибо за это. Я счастлив отметить это как правильное.

user5283119 27.01.2019 01:08

вы также можете написать это так: {Object.keys (this.state.error) .length> 0 && <Text> Сообщение об ошибке: {this.state.error} </Text>}

MING WU 02.09.2019 03:00

Просто удалите комментарии из кода, тогда все будет нормально. Кстати, другой альтернативы я не знаю! :)

Пожалуйста, подумайте о прочтении других ответов, прежде чем давать свои собственные, поскольку об этом уже упоминала Таре Гаскин.

user5283119 24.02.2019 13:08

Я бы использовал !!, который я называю оператором bang bang, чтобы булинизировать error. Это должно сработать.


{!!this.state.error && (
  <Text>
    Error message: {this.state.error}
  </Text>
)}

Если error является строкой, ваш текст должен быть заключен в <Text />, как говорится в сообщении об ошибке в React Native, который отличается от веб-интерфейса.

На реакции 59.9 это исправило ошибку для меня. Оказывается, значение было пустой строкой. Как ни странно, ошибка произошла только в Android.

twelve17 17.08.2019 13:54
 <React.Fragment>
      {this.props.title ? (
        <React.Fragment> 
          <Text>  true </Text>
        </React.Fragment>
        ):(             
           <React.Fragment> 
          <Text>  false </Text>
          <Text>  false </Text>
        </React.Fragment>

Вам нужно обернуть тегом Вид или тегом React.Fragment, а внутри вам также нужно обернуть, если элемент более одного

попробуй это :

<>
    <View>
    {this.state.error &&
      <Text>
        Error message: {this.state.error}
    </Text>
   </View>
</>

Я столкнулся с тем же сообщением об ошибке в VSCode, но у меня не было / * комментариев * / или каких-либо выражений. Решением было удалить форматирование в чем-то вроде textedit или word и скопировать + вставить код обратно в vscode.

Я не знаю, почему и как это работает (возможно, это происходит конкретно в VSCode), но проблема форматирования - это то, с чем я также столкнулся с SDL в graphql ...

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

Всякий раз, когда вы видите

Invariant Violation: Text strings must be rendered within a <Text> component

99% случаев будут вызваны использованием условного рендеринга только с && вместо тернарного? : заявления. Почему? Потому что, когда ваше условие разрешается в неопределенный, там нет компонентов, в отличие от нулевого или пустого массива, который безопасно показал бы пустое пространство и спас бы вашу жизнь от красного экрана ада.

Измените ВСЕ ВАШИ ЛОГИЧЕСКИЕ УСЛОВНЫЕ РЕНДЕРЫ на троичные представления.

то есть:

НЕ ДЕЛАЙТЕ

widgetNumber === 10 && <MyComponent />

ДЕЛАТЬ

widgetNumber === 10 ? <MyComponent /> : null

Каждый раз. Пожалуйста. Из любви к родному реагирую.

Лучший ответ! Этот подход с использованием тернарного оператора кажется мне намного более сильной идеей по сравнению с использованием этого !!this.state.error &&.

Mark Colling 05.03.2020 07:51

Спасибо @MarkColling

serdarsenay 06.03.2020 00:48

Действительно лучший. Спаситель жизни!

domster 09.05.2020 20:50

Спасибо @serdarsenay!

Scott 08.07.2020 21:53

@NickTiberi это работает, потому что, когда вы возвращаете пустой объект, он не является допустимым компонентом для возврата для рендеринга, однако пустой массив есть. Когда у вас есть условный блок и условие ложно, и у вас нет возвращенного запасного компонента или массива, нарушение инварианта происходит из-за того, что возвращается недопустимый компонент. Надеюсь это поможет.

serdarsenay 01.10.2020 05:01

Возврат null вместо пустого массива также работает и, возможно, семантически лучше подходит.

ToneCrate 08.12.2020 09:52

@serdarsenay спасибо, вы сохранили мое приложение, которое я отлаживаю уже несколько часов. ToneCrate Я согласен с вами, что null - это семантическое соответствие.

Cuado 22.02.2021 10:25

Еще одна вещь, которую вы можете сделать вместо троичного выше, - это преобразовать свое выражение во что-то вроде Boolean (myString) && <MyJSX />

Shn_Android_Dev 24.03.2021 20:40

Это лучший ответ, поскольку в этом случае сообщение об ошибке не помогает. Спасибо!

Grant Singleton 16.06.2021 18:05

Вы герой сэр

Cayo Eduardo 02.07.2021 23:34

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

Vinicius Vasconcelos 04.07.2021 07:33

Хотел бы я проголосовать за это еще несколько раз.

Mnebuerquo 09.08.2021 22:29

В моем случае эта ошибка возникла из-за наличия точки с запятой ';' в конце закрытия текстового тега. Для всех тех, кто не получил подходящего ответа выше, попробуйте это. Убрав точку с запятой, ошибка исчезла.

Для меня это произошло из-за неоткрытой фигурной скобки внутри JSX.

<View>
        {events.map(event => {
          return (
            <Card title = {event.summary}>
              <Text>Date: {event.start.dateTime}</Text>
            </Card>
          );
        })}
        } <------------ that was the culprit
</View>
this.state.recording ?(<Text>{this.secondsToMMSS(this.state.seconds)}</Text>) :                                     (null)

текстовая строка должна отображаться в компоненте

{this.state.password.length > 0 && <Text>}

Это вызовет ту же ошибку, потому что возвращает undefined. Мы можем сделать это так -

{this.state.password.length > ? <Text> : null}
In my case some part of the code was out side the text component for example:
<RadioForm style = {styles.radiobutton} 
                      radio_props = {hobbies}
                      initial = {1}
                      onPress = {(value) => {ToastAndroid.show(value.toString(), ToastAndroid.SHORT)}}
                      buttonSize = {4.5}
                      buttonOuterSize = {19}
                      selectedButtonColor = {'green'}
                      selectedLabelColor = {'green'}
                      labelStyle = {{ fontSize: 14, }}
                      disabled = {false}
                      formHorizontal = {true}
             />
<RadioForm

эта строка выше <RadioForm остается незакрытой, что является причиной

Прочитав другие ответы здесь, это сообщение об ошибке расплывчато и отображается по разным причинам. У меня это получалось при написании комментариев или даже при небольших пробелах в представлениях (безумно, да ...)

например: <View> {props.children} </View>

необходимо изменить на: <View>{props.children}</View>

У меня была та же проблема, и ошибка заключалась в добавлении пробела между дочерними элементами и компонентом, например {children}

Примечание: удалите все места рядом с {children}

 <Provider value = {something}>{children}</BlogContext.Provider>

Это произошло со мной, потому что я случайно использовал имя функции в нижнем регистре:

export const p = (props) => {
  return (
    <Text style = {[styles.p]}>{props.children}</Text>
  );
};

Должно быть:

export const P = (props) => {
  return (
    <Text style = {[styles.p]}>{props.children}</Text>
  );
};

Обратите внимание, что во втором p пишется с заглавной буквы. Это необходимо для того, чтобы компоненты определялись как компоненты React Native.

У меня такая же проблема, В моем случае у меня был компонент <AppText>, который показывает под капотом простой форматированный <Text>.

Первый код был похож на

<AppText> </AppText>

пока я пробовал разные вещи, я просто написал его с самозакрывающимся синтаксисом

<AppText />

затем проблема была внезапно решена.

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

В моем случае это произошло из-за того, что комментарии в функции рендеринга

// Some comment here

Решения:

  • Удалить комментарий
  • или сделать вот так {/* Same comment here*/}

Иногда Prettier или программа форматирования кода добавляют это в ваш JSX при сохранении.

<View>
{' '}
</View>

Удалите это, и все будет в порядке.

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

{this.state.error !== '' && (
    <Text>
      {this.state.error}
    </Text>
)}

Была та же проблема, и комментарий @serdasenay заставил меня понять основную причину.

Использование синтаксиса {condition && <Element/>} само по себе не является неправильным, но важно знать, что происходит.

Корень проблемы - короткое замыкание логики. В выражениях логики Javascript оценивается, а && оценивает последнее эквивалентное значение true. Но не в true, а в фактическое значение перед преобразованием в логическое. Это то, с чего фактически можно начать этот синтаксис. Поскольку <Element/> всегда является true, если condition является true, выражение оценивается как <Element/>.

Проблема возникает при условии false. Когда выражение && терпит неудачу, оно возвращает первое значение, то есть condition. Но до того, как он будет преобразован в логическое значение. Итак, если вы используете прямую строку или число как condition, и оно оценивается как false, логическое выражение будет оценивать эту строку или число. Пример: {array.length && <List/>} с пустым массивом оценивается как {0}, что вызывает ошибку.

Решение состоит в том, чтобы убедиться, что condition является реальным логическим значением (и это работает, потому что React может иметь дело с логическими значениями рендеринга - он думает, что React просто игнорирует их). Так что сделайте следующее: {array.length > 0 && <List/>}

Спасибо! Так случилось и со мной.

user8212309 10.01.2021 10:51

Эта ошибка возникает, когда у вас есть /*Commented code*/ в вашей функции return().

Потратил значительную часть дня на выполнение совершенно несвязанных задач, чтобы попытаться исправить это.

Есть оператор !! который преобразует строковый тип в логический и делает его ложным, если переменная является пустой строкой:

{!!error &&
  <Text>
    Error message: {error}
</Text>}

Для меня это было из-за неправильного закрытия > в TouchableOpacity Реагировать на родную сенсорную непрозрачность.

Неверный код:

<TouchableOpacity>
        onPress = {() => this.setState({ showOverLay: true })}
          <Image
            source = {cardImage}
            resizeMode = "contain"
            style = {[
              styles.cardImage, cardImageStyle
            ]}
          />
</TouchableOpacity>

Хороший код:

  <TouchableOpacity
        onPress = {() => this.setState({ showOverLay: true })}>
          <Image
            source = {cardImage}
            resizeMode = "contain"
            style = {[
              styles.cardImage, cardImageStyle
            ]}
          />
</TouchableOpacity>

В моем случае мне пришлось удалить пробел между тегом View и тегом Text. из

<View>  <Text style = {{ color: "white"}}>Start</Text> </View>

к

<View><Text style = {{ color: "white"}}>Start</Text></View>

хорошо, так что если вы зашли так далеко, это потому, что у вас, вероятно, такие же проблемы, как, например, у меня:

вернуть {columns}

а также:

вернуть {строки}

вы видите пробел между "> {" да, в этом вся проблема, попробуйте их удалить.

Этот код ниже также проверяет пустую строку и истинное значение.

  return(
    <View>
    {!!this.state.error && <Text>{this.state.errorMessage}</Text>}
    </View>
  );

Для меня ошибка заключалась в том, что я инициализировал объект состояния как пустую строку.

const [category, setCategory] = useState("")

Если состояние будет объектом, то вначале для него должно быть установлено значение null.

const [category, setCategory] = useState(null)

Решил проблему.

Удалить пространство между компонентами снаружи

<Text></Text>

Бывший. Не использовать

<Button> <Text>hi</Text></Button> 

Но используйте

<Button><Text>hi</Text></Button>

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