0

Can life cycles be used in Arrow functions using componentDidMount() and having an error my only response I tried to add a useEffect ? Trying to Converting class components to functional components.
I created a contentful blog in a separate project below and would like to add my blog to my blog.js page in my main project.

Original contentful blog that works.

Blog.js

import React from "react";
import "./App.css";
import { client } from "./client";
import Posts from "./components/blog/Posts";

class App extends React.Component {
  state = {
    articles: [],
  };

  componentDidMount() {
    client
      .getEntries()
      .then((response) => {
        console.log(response);
        this.setState({
          articles: response.items,
        });
      })
      .catch(console.error);
  }

  render() {
    return (
      <div className="App">
        <div className="container">
          <header>
            <div className="wrapper">
              <span>React and Content</span>
            </div>
          </header>
          <main>
            <div className="blog__page">
              <h1 class="blog__page__header">ZILAH MUSIC PUBLISHING NEWS</h1>
              <div className="blogs">
                <div className="wrapper">
                  <Posts posts={this.state.articles} />
                </div>
              </div>
            </div>
          </main>
        </div>
      </div>
    );
  }
}

export default App;

I added a useEffect and now my state is undefined

 useEffect(() => {
    client
      .getEntries()
      .then((response) => {
        console.log(response);
        this.setState({
          articles: response.items,
        });
      })
      .catch(console.error);
  }, []);

I duplicated my previous running pages and would like to include my blog but I have an issue convertingenter image description here

import React, { useEffect, useState } from "react";
import { Link, Redirect } from "react-router-dom";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { client } from "../../client";
import Posts from "../../components/blog/Posts";

import "./Blog.css";

class App extends React.Component inside an arrow function

const Blog = ({ isAuthenticated }) => {
  if (isAuthenticated) {
    return <Redirect to="/dashboard" />;
  }


useEffect(() => {
        client
          .getEntries()
          .then((response) => {
            console.log(response);
            this.setState({
              articles: response.items,
            });
          })
          .catch(console.error);
      }, []);

  return (
    <React.Fragment>
      <div className="App">
      <div className="container">
          <header>
            <div className="wrapper">
              <span>React and Content</span>
            </div>
          </header>
          <main>
            <div className="blog__page">
              <h1 className="blog__page__header">
                ZILAH MUSIC PUBLISHING NEWS
              </h1>
              <div className="blogs">
                <div className="wrapper">
                  <Posts posts={this.state.articles} />
                </div>
              </div>
            </div>
          </main>
        </div>
      </div>
    </React.Fragment>
  );
};

Bog.propTypes = {
  isAuthenticated: PropTypes.bool,
};

const mapStateToProps = (state) => ({
  isAuthenticated: state.auth.isAuthenticated,
});

export default connect(mapStateToProps)(Blog);
concepttech
  • 17
  • 2
  • 9

2 Answers2

1

Function components use the useState hook instead of this.setState and this.state (https://reactjs.org/docs/hooks-state.html).

At the top of your function component, add this (make sure to import useState from 'react' like you did with useEffect):

const Blog = ({ isAuthenticated }) => {
  const [articles, setArticles] = useState([]);
  //... etc

Then, instead of this.setState() use:

setArticles(response.items);

And, in the body:

<div className="wrapper">
  <Posts posts={articles} />
</div>

The title of your post (expected parameter accessToken) seems unrelated to the problem you mention part way through saying that your state is undefined, which is what this answer addresses

jnpdx
  • 45,847
  • 6
  • 64
  • 94
  • Do you mean to add in place of – concepttech Mar 05 '21 at 20:55
  • Yes -- you will no longer be able to refer to `this.state` in function components. – jnpdx Mar 05 '21 at 20:56
  • Still doesn't work having an error React Hook "useState" cannot be called at the top level. I sttill recieve an error of React Hook "useEffect" is called conditionally. – concepttech Mar 05 '21 at 23:21
  • You've put it at the wrong place. Look at my example -- it should directly follow the line `const Blog = ({ isAuthenticated }) => {` – jnpdx Mar 05 '21 at 23:22
0

I updated my code and recieved this error. src\components\layout\Blog.js Line 16:35: React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return? react-hooks/rules-of-hooks Line 18:3: React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return? react-hooks/rules-of-hooks

import React, { useEffect, useState } from "react";
import { Link, Redirect } from "react-router-dom";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { client } from "../../client";
import Posts from "../../components/blog/Posts";

import "./Blog.css";
import BlogConnect from "./BlogConnect";

const Blog = ({ isAuthenticated }) => {
  if (isAuthenticated) {
    return <Redirect to="/dashboard" />;
  }

  const [articles, setArticles] = useState([]);

  useEffect(() => {
    client
      .getEntries()
      .then((response) => {
        console.log(response);
        setArticles(response.items);
      })
      .catch(console.error);
  }, []);

  return (
    <React.Fragment>
      <div className="App">
        <div className="container">
          <header>
            <div className="wrapper">
              <span>React and Content</span>
            </div>
          </header>
          <main>
            <div className="blog__page">
              <h1 className="blog__page__header">
                ZILAH MUSIC PUBLISHING NEWS
              </h1>
              <div className="blogs">
                <div className="wrapper">
                  <Posts posts={articles} />
                </div>
              </div>
            </div>
          </main>
        </div>
      </div>
    </React.Fragment>
  );
};

Blog.propTypes = {
  isAuthenticated: PropTypes.bool,
};

const mapStateToProps = (state) => ({
  isAuthenticated: state.auth.isAuthenticated,
});

export default connect(mapStateToProps)(Blog);
concepttech
  • 17
  • 2
  • 9
  • You should edit your post -- not add this as an answer. The useState line needs to go at the *top* of the function component, before `if (isAuthenticated)`. See my updated answer. – jnpdx Mar 05 '21 at 21:01
  • Thanks i appreciate your help to simplify the problem so i can understand. – concepttech Mar 08 '21 at 16:27
  • my issue with the componentDidMount() and useeffect is solved but i have a new a new error of Expected parameter accessToken – concepttech Mar 08 '21 at 20:16
  • You aren't showing any code with accessToken in it. If my answer solved the initial question, I would ask that you accept the answer (the green checkmark) and then start a new question showing the code necessary to illustrate the other problem. – jnpdx Mar 08 '21 at 20:18
  • I checked the (the green checkmark) and added a new questions. thanks for your help again new to the platform and getting a custom to it. – concepttech Mar 08 '21 at 20:25
  • Hmm -- my answer isn't showing up as accepted to me – jnpdx Mar 08 '21 at 20:49