RussellHarrower
RussellHarrower

Reputation: 6820

Next-Auth & React.Component

Next-Auth has the following example which is great for functions, however I have a class which I need to run const { data: session } = useSession() in it. I am wondering how can I convert it to make it valid in a class?

export default function AdminDashboard() {
  const { data: session } = useSession()
  // session is always non-null inside this page, all the way down the React tree.
  return "Some super secret dashboard"
}

AdminDashboard.auth = true

I tried to add session: useSession() to the following constructor but it did not work.

My Class

export default class AdminDashboard extends React.Component {
 constructor(props) {
        super(props);
        this.state = {
          value: null,
          areas:[],
          areasid:[],
          users: [],
          isLoading: true,
          isAreaLoading: true,
          session: useSession() // THIS DID NOT WORK
        };
        this.checkAnswer = this.checkAnswer.bind(this);
        
      }
}
AdminDashboard.auth = true

based on the answer below. I changed the script to be like this

const withSession = (Component) => (props) => {
  const session = useSession()

  // if the component has a render property, we are good
  if (Component.prototype.render) {
    return <Component session={session} {...props} />
  }

  // if the passed component is a function component, there is no need for this wrapper
  throw new Error(
    [
      "You passed a function component, `withSession` is not needed.",
      "You can `useSession` directly in your component.",
    ].join("\n")
  )
}



export default class NewCampaign extends React.Component {
render(){
        const { data: session, status } = this.props.session;
        const { isLoading, users, areas, areasid, isAreaLoading } = this.state;
        return (
            <React.Fragment></React.Fragment>
         )}
}

const ClassComponentWithSession = withSession(NewCampaign)

NewCampaign.auth = false;

NewCampaign.getLayout = function getLayout(page) {
  return (
    <Dashboard>
      {page}
    </Dashboard>
  )
}

However, I am getting Cannot destructure property 'data' of 'this.props.session' as it is undefined.

Upvotes: 1

Views: 1128

Answers (2)

Ivan V.
Ivan V.

Reputation: 8101

You should use getSession and just await the result.

async function myFunction() {
  const session = await getSession()
  // session available here
}

You can use it both on client and the server.

Upvotes: 2

A G
A G

Reputation: 22597

If you want to use the useSession() hook in your class components you can do so with the help of a higher order component or with a render prop.

Higher Order Component

import { useSession } from "next-auth/react"

const withSession = (Component) => (props) => {
  const session = useSession()

  // if the component has a render property, we are good
  if (Component.prototype.render) {
    return <Component session={session} {...props} />
  }

  // if the passed component is a function component, there is no need for this wrapper
  throw new Error(
    [
      "You passed a function component, `withSession` is not needed.",
      "You can `useSession` directly in your component.",
    ].join("\n")
  )
}

// Usage
class ClassComponent extends React.Component {
  render() {
    const { data: session, status } = this.props.session
    return null
  }
}

const ClassComponentWithSession = withSession(ClassComponent)

Render Prop

import { useSession } from "next-auth/react"

const UseSession = ({ children }) => {
  const session = useSession()
  return children(session)
}

// Usage
class ClassComponent extends React.Component {
  render() {
    return (
      <UseSession>
        {(session) => <pre>{JSON.stringify(session, null, 2)}</pre>}
      </UseSession>
    )
  }
}

Upvotes: 0

Related Questions