Comments (4)
你好,我看了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.
你好,我看了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.
感谢提示哈,的确如你所说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 i
并 npm run dev
来测试
post-page
是一个标准的服务端预渲染页面。
ps: getServerSideProps 也是同样类似的做法来做哦,它们只是执行时机不同,getServerSideProps是每次请求页面都会执行,而getStaticProps是构建时执行。
from helux.
close
from helux.
Related Issues (20)
- 导出 ICtxBase 接口给 ctx 指定后,调用 dispatch 返回类型强制变成了unknown HOT 2
- 有计划抽离concent吗?更加纤细
- 为何版本从2020就停止维护了? HOT 5
- Rebuild the project with Typescript. HOT 1
- reducer中ac.dispatch派发的函数调用,loading插件捕获不到? HOT 2
- 修改既修改私有状态也修改模块状态的问题 HOT 1
- 使用中感到难受疑惑的点 HOT 7
- 更新到2.16.4之后出现了报错 HOT 3
- 文档字段错误 HOT 2
- [交流] 新状态库,求拍砖 HOT 6
- 关于 state 和 moduleState 的疑问 HOT 10
- 实例的watch监听对undefined不生效 HOT 3
- 关于 dispatch 的 callback 问题 HOT 3
- 无法与 Next 12.1.0 一起使用 HOT 4
- 连接的模块无法触发更新!!! HOT 3
- 支持react18并发模式 HOT 4
- 和jotai ,valtio 的对比有吗, 另外readme里的教程用的还是class,有function版本的吗 HOT 4
- 虽然小众 但初步用起来真香 类似vuex存储就行 而setup是惊喜分离了数据逻辑 HOT 6
- [bug] v2.19.12: react Invalid hook call HOT 3
- 【bug】reducer的payload为数组时 数组赋值的同时被展开挂载到根状态上 HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from helux.