Нарушение инварианта: хуки могут вызываться только внутри тела компонента функции - PullRequest
0 голосов
/ 04 декабря 2018

TL; DR: Я пытаюсь использовать новый react-hooks API, но продолжаю получать ошибку Invariant Violation при вызове ловушки setState, но она продолжает давать сбой.

import React, { useState } from 'react';

// type State = {
//   heading: string;
// }

const Text = () => {
  const initialState = 'Heading'.toUpperCase();

  const [heading, setHeading] = useState(initialState);

  return (
    <header>
      <h1>
        {setHeading('Brussels')};
        {heading}
      </h1>
    </header>
  );
};

export default Text;

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Если вы вспомните версию компонента класса, ваш код вызывает this.setState в render(), который вызовет другой рендеринг, и снова вызывает this.setState, и цикл повторяется, и вы получите ошибку:

Uncaught Error: Слишком много повторных визуализаций.React ограничивает количество визуализаций, чтобы предотвратить бесконечный цикл.

Вы бы не вызвали this.setState непосредственно в вашем методе рендеринга, и при этом вы не должны делать это с помощью хуков.

Этонеясно, чего вы пытаетесь достичь здесь, но я думаю, что вам нужно установить имя только один раз, что вы бы сделали в componentDidMount, и вы можете использовать хук useEffect для достижения этого.

Или, если вы хотите, чтобы «Брюссель» был начальным состоянием, передайте его как значение в useState().

const {useState, useEffect} = React;

const Text = () => {
  const initialState = 'Heading'.toUpperCase();
  const [heading, setHeading] = useState(initialState);
  useEffect(() => {
    setHeading('Brussels');
  }, []); // Pass in empty array to simulate componentDidMount.
  
  return (
    <header>
      <h1>
        {heading}
      </h1>
    </header>
  );
};

ReactDOM.render(<Text />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
0 голосов
/ 04 декабря 2018

Вызов setHeading ("Brussel") будет вызывать повторный рендеринг снова и снова, что в свою очередь приводит к бесконечному циклу, что предотвращает необходимость в событии для изменения заголовка с "Заголовок" на "Брюссель".Ниже код может помочь вам

const Text = () => {
const initialState= 'Heading'.toUpperCase();
const [heading, setHeading] = useState(initialState);  
return (
 <header>
    <h1>
    {heading}
    <button onClick= {() =>{setHeading("Brussel")}}>ChangeName</button>
    </h1>
    </header>
);
};
...