React Hooks можно вызывать только внутри тела компонента функции - PullRequest
0 голосов
/ 11 ноября 2018

Как мне вызвать useEffect() при нажатии кнопки, а не при рендеринге компонента?

Когда я использую ее внутри такой функции, я получаю сообщение об ошибке:

Хуки можно вызывать только внутри тела компонента функции

function App() {

  function buttonClicked() {  
    useEffect(() => {
      // Fetch from API
    });
  }

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <h1 className="App-title">App Title</h1>
      </header>
      <p className="App-intro">
        To get started, edit <code>src/App.js</code> and save to reload.
      </p>
      <button onClick={buttonClicked}>Make API Call</button>
    </div>
  );
}

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

Принятый ответ не совсем правильный IMO. Если ваша цель - запустить выборку данных при нажатии на кнопку, нет необходимости в useEffect. useEffect используется для замены хуков жизненного цикла - componentDidMount, componentDidUpdate и componentWillUnmount.

Подумайте об этом - без крючков, понадобятся ли вам эти крючки жизненного цикла для достижения того, чего вы хотите? С классами вам просто нужно использовать this.state и обратный вызов, который срабатывает при нажатии кнопки; Вы не будете использовать ни один из этих крючков жизненного цикла.

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

Приведенный ниже код должен делать то, что вы хотите достичь с помощью хуков, и вам не нужно useEffect, вам нужен только useState.

function App() {
  const [user, setUser] = React.useState(null);

  function fetchData() {
    fetch('https://randomuser.me/api/')
      .then(results => results.json())
      .then(data => {
        setUser(data.results[0]);
      });
  };
  
  return <div>
    <p>{user ? user.name.first : 'No data'}</p>
    <button onClick={fetchData}>Fetch Data</button>
  </div>;
}

ReactDOM.render(<App/>, document.getElementById('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 голосов
/ 11 ноября 2018

Похоже, вы неправильно поняли использование useEffect. Это как componentDidUpdate hook - он запускается в зависимости от изменения значения, а не напрямую какой-либо функцией. Когда вызывается метод render, также вызывается useEffect. Трудно сказать, какова ваша цель, но из вашего фрагмента наиболее разумно просто позвонить fetch без каких-либо хуков. Но чтобы ответить на ваш вопрос, один из способов вызвать useEffect - это обновить ваше состояние, и вы можете создать useEffect ловушку, которая будет срабатывать только при изменении значения определенного свойства:

const [buttonClicked, setButtonClicked] = useState(false);

useEffect(() => {
  // Fetch from API
}, [buttonClicked]); 

<button onClick={() => setButtonClicked(true)}>Make API Call</button>

Теперь, когда вы нажимаете, useEffect должен быть запущен, но поскольку вы добавили , [buttonClicked], он не будет вызван, если изменится любое другое значение свойства.

...