13733

Unable to pass props in Next

<h3>Question</h3>

I am making a Server Side Rendering application using Next Js (React SSR).

Index.js (Simply calling another component Layout in index)

import Layout from "./layout"; import React from "react"; class Home extends React.Component { render() { return ( <div> <Layout /> </div> ); } } export default Home;

Layout.js

import React from "react"; import Product from "./product"; class Layout extends React.Component { static async getInitialProps() { const res = await fetch("https://api.github.com/repos/developit/preact"); console.log(res); const json = await res.json(); return { stars: json.stargazers_count }; } componentDidMount() { if (localStorage.getItem("userLoggedIn")) { //Get products details for logged in user api //For now let us consider the same api // const res = fetch("https://api.github.com/repos/developit/preact"); // const json = res.json(); // better use it inside try .. catch // return { stars: json.stargazers_count }; } else { // Get product details for guest user api //For now let us consider the same api // const res = fetch("https://api.github.com/repos/developit/preact"); // const json = res.json(); // return { stars: json.stargazers_count }; } } render() { return ( <div> This is layout page <Product stars={this.props.stars} /> </div> ); } } export default Layout;

Complete simple application example is here: https://codesandbox.io/s/nextjs-getinitialprops-748d5

My problem here is, I am trying to pass props to product page from layout page and props are received from getInitialProps (SSR).. But you could see in the example provided, the props didn't works and it still gives undefined for this.props.stars .

If I move this code into componentDidMount and using setState and passing state as props would work but that will not display the data fetched from api in view page source.

Note: Please don't move this logic into index.js file where it works but in my real application It is dynamic routing page and I will fetch api as per the query param fetched on that page.

If you get into this link https://748d5.sse.codesandbox.io/ and click ctrl + u then you would see the source where I am also need the dynamic content fetched from api.

To achieve this dynamic content(stars count here in this example) display in view source only I am doing all these which is meant for SEO purpose.


<h3>Answer1:</h3>

In short, you can't call getInitialProps from a child component: getInitialProps caveats.

<blockquote>

getInitialProps can not be used in children components, only in the default export of every page

</blockquote>

Your Layout page is a child component of Home.

If you want to call getInitialProps, then you'll either need to define getInitialProps from within the Home page OR create a wrapper component that calls its own getInitialProps that will wrap the page's default export PageComponet with this wrapper component: export default withStarsData(PageComponent); as a result, this wrapper component will then pass PageComponent some props.

If you want to make this function flexible/dynamic, then use ctx's query parameter with a dynamic route.

This is a rather complex solution to understand, but in brief, it allows the home (/) and layout (/layout) pages to fetch the same data. If you don't want to fetch the data multiple times, but instead, fetch ONCE and then share between pages, then you'll want to use a higher-order state provider like redux.

Working example:

<hr />

components/withStars/index.js

import React from "react"; import fetch from "isomorphic-unfetch"; // 1.) this function accepts a page Component and... const withStars = WrappedComponent => { // 7.) if stars data is present, returns <WrappedComponent {...props} /> with props // else if there's an error, returns the error // else returns a "Loading..." indicator const FetchStarsData = props => props.stars ? ( <WrappedComponent {...props} /> ) : props.error ? ( <div>Fetch error: {props.error} </div> ) : ( <div>Loading...</div> ); // 3.) this first calls the above function's getInitialProps FetchStarsData.getInitialProps = async ctx => { // 4.) here's where we fetch "stars" data let stars; let error; try { const res = await fetch("https://api.github.com/repos/developit/preact"); const json = await res.json(); stars = json.stargazers_count; } catch (e) { error = e.toString(); } // 5.) optionally this will call the <WrappedComponent/> // getInitialProps if it has been defined if (WrappedComponent.getInitialProps) await WrappedComponent.getInitialProps(ctx); // 6.) this returns stars/error data to the FetchStarsData function above return { stars, error }; }; // 2.) ...returns the result of the "FetchStarsData" function return FetchStarsData; }; export default withStars;

来源:https://stackoverflow.com/questions/61111933/unable-to-pass-props-in-next

Recommend

  • How To Crop Captured Image? --C#
  • validation for kafka topic messages
  • InputMethodManager show numpad in webview
  • Jasper reports - Cambodian / Khmer and Laotian Language
  • GetPrivateProfileString - Buffer length
  • How to make a universal app
  • Get the name of provisioning profile in xcode
  • Allocate string (char*) in another function
  • One-to-many relationship getting error in Entity Framework Core when trying to insert data
  • Laravel 5 multi level category
  • Prime numbers c++
  • channels without channel layer or any other free hosting
  • ng-repeat in repeat does not repeat nested object angular
  • expand ipv6 address in shell script
  • Condition on a timestamp column to select data for a year
  • How can I send data in text field using Selenium?
  • Eloquent Javascript: Can't understand how the number value is determined in the sum function
  • How to gracefully stop python unittest?
  • wxpython passing information, pointers?
  • React / Webpack - “Module parse failed: Unexpected token - You may need an appropriate loader to han
  • How to copy memory
  • plot dirac function in matlab
  • Corda: How to implement hierarchical relationships between state data persisted to H2
  • jQuery Ajax call to WCF service returning “Method not allowed (405)”
  • Excel Reverse Match
  • Javascript inside HTML import not affecting imported HTML
  • Keep rows with certain values always at the bottom while sorting in jquery tablesorter plugin
  • Debugging php script timeout?
  • How to use Typescript with libraries like Ampersand.js that parse configs to build prototypes
  • python selenium scraping tbody
  • How to redirect into different page by user type in php and mysql
  • How do I use libcurl to printf a remote FTP directory listing?
  • Google Spreadsheet Script to Blink a range of Cells
  • JQuery: Infinite input select
  • How to encrypt Connectionstring written in web.config from codebehind?
  • Computing the discrete fourier transform of audio data with FFTW
  • Using Service Component Runtime
  • convert json to excel in java
  • Create/delete users from text file using Bash script