Git Product home page Git Product logo

Comments (4)

fantasticsoul avatar fantasticsoul commented on May 22, 2024

你好,我看了next.js 文档 https://www.nextjs.cn/docs/basic-features/pages , 你提到的 getStaticProps是next提供一个功能,是可以和concent协同起来,

例如以下原始示例

function Blog({ posts }) {
  // Render posts...
}

// 此函数在构建时被调用
export async function getStaticProps() {
  // 调用外部 API 获取博文列表
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // 通过返回 { props: posts } 对象,Blog 模块
  // 在构建时将接收到 `posts` 参数
  return {
    props: {
      posts,
    },
  }
}

export default Blog

稍加改造后

// ###### runConcent.js里的代码 ######
run({
  postModule: {
    state: { posts: null },
  }
})

// ###### 组件里的代码 ######
function Blog({ posts }) {
  const { setState, state } = useConcent('postModule');
  React.useEffect(()=>{
     setState({posts}); // 数据同步到store
  }, [posts]);
  const targetPosts = state.posts || posts; // 优先取模块状态,再取props.posts
}

// 此函数在构建时被调用
export async function getStaticProps() {/** ... */}

关于concent的nextjs实例可以看这里来参考和改造
https://github.com/concentjs/ssr-demo-1

from helux.

J-env avatar J-env commented on May 22, 2024

你好,我看了next.js 文档 https://www.nextjs.cn/docs/basic-features/pages , 你提到的 getStaticProps是next提供一个功能,是可以和concent协同起来,

例如以下原始示例

function Blog({ posts }) {
  // Render posts...
}

// 此函数在构建时被调用
export async function getStaticProps() {
  // 调用外部 API 获取博文列表
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // 通过返回 { props: posts } 对象,Blog 模块
  // 在构建时将接收到 `posts` 参数
  return {
    props: {
      posts,
    },
  }
}

export default Blog

稍加改造后

// ###### runConcent.js里的代码 ######
run({
  postModule: {
    state: { posts: null },
  }
})

// ###### 组件里的代码 ######
function Blog({ posts }) {
  const { setState, state } = useConcent('postModule');
  React.useEffect(()=>{
     setState({posts}); // 数据同步到store
  }, [posts]);
  const targetPosts = state.posts || posts; // 优先取模块状态,再取props.posts
}

// 此函数在构建时被调用
export async function getStaticProps() {/** ... */}

关于concent的nextjs实例可以看这里来参考和改造
https://github.com/concentjs/ssr-demo-1

这样不行,useEffect 服务端不执行的,Blog组件的props. posts不可能一层一层的传给子组件吧,需要的是在其他组件直接就可以拿到需要的数据

from helux.

fantasticsoul avatar fantasticsoul commented on May 22, 2024

感谢提示哈,的确如你所说useEffect在服务端是不会执行的,所以我仔细研究了nextjs的 getStaticProps 的执行流程,如果next发现在组件发现包含有这个函数时,会先执行一遍这个函数拿到数据后再开始渲染组件,而next的渲染根组件是约定的_app.js文件,内容如下

import '../styles/globals.css'

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

export default MyApp

注意上面的 pageProps,就是getStaticProps的返回结果,所以我们能够在page组件的props上能拿到getStaticProps的返回数据是因为这里做了透传。

所以改造点就可以以此为突破口了,我们把getStaticProps的返回结果做一下格式约束,形如{module:string, state: object}这样的解构,如:

// 此函数在构建时被调用
export async function getStaticProps() {
  // 调用外部 API 获取博文列表
  await delay();
  const posts = [
    { id: 1, name: 'post1 -----' },
    { id: 2, name: 'post2 --- welcome to use concent' },
  ];

  // 这个返回对象会透传给 根组件的pageProps,
  // 在此返回状态所属的模块,和状态实体对象
  // 在那里将状态记录到store
  return {
    props: {
      module: 'test',
      state: { posts },
    }
  };
}

而此时_app.js的内容如下

import '../styles/globals.css'
import './runConcent'
import { setState } from 'concent';

function MyApp({ Component, pageProps }) {

  // 这里记录 getStaticProps 的返回状态到store的对应模块
  if (pageProps.module) {
    setState(pageProps.module, pageProps.state);
  }
  
 // 这里透传与否都无所谓了,因为所有子孙组件不是从props读取数据了
  return <Component {...pageProps} />
}

export default MyApp

然后我们的组件代码如下:

const PostList = React.memo(function () {
  /** @type Ctx */
  const { state } = useConcent('test');
  return (
    <div>
      {state.posts.map(item => <h3 key={item.id}>{item.name}</h3>)}
    </div>
  );
});

const PostLength = React.memo(function () {
  /** @type Ctx */
  const { state } = useConcent('test');
  return <h1>{state.posts.length}</h1>;
});

export default function PostPage(props) {
 // 这里完全可以不需要读取 props 数据了,所有子组件可以从concent的store里获取到数据
  return (
    <div>
      <h1>this is post page</h1>
      <PostList />
      <PostLength />
      <button onClick={toHomePage}>to home page</button>
    </div>
  );
}

最新的代码已经push到这个库了
https://github.com/concentjs/ssr-demo-1/tree/master/pages
测试页面是post-page,欢迎clone,然后npm inpm run dev来测试
post-page是一个标准的服务端预渲染页面。

ps: getServerSideProps 也是同样类似的做法来做哦,它们只是执行时机不同,getServerSideProps是每次请求页面都会执行,而getStaticProps是构建时执行。

from helux.

fantasticsoul avatar fantasticsoul commented on May 22, 2024

close

from helux.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.