【发布时间】:2020-03-10 17:23:31
【问题描述】:
我知道这是一个很长的介绍,但我真的很难在这里表达清楚
在我正在处理的这个Next.js 应用程序中,我需要在具有特定id 的div 上设置一个CSS 网格布局。我用样式组件createGlobalStyle 来做这件事。我希望这个 App 组件的每个子组件都能够更改此网格布局(可选地传入替代 CSS 值)。
我已经在状态中设置了默认的网格 CSS 值(回退,以防子函数未调用)。我创建了一个类方法 (setLayout),它可以使用接收到的参数设置布局状态。我将这个函数的引用传递给每个带有 React Context 的子组件。
在我的子组件中,我现在可以导入此上下文并使用替代布局调用函数。有用。但是......当我首先刷新页面时,后备布局会在子组件布局应用于根 div 之前闪烁一秒钟。
换句话说,在第一次渲染时,App 组件会使用回退值进行渲染,然后子组件会调用一个函数来渲染,该函数会更改 App 组件的状态,从而触发重新渲染。然后在第二次渲染时,App 组件以正确的布局渲染。
我真的希望 App 组件在第一次渲染时渲染子提供的布局(如果提供的话),而不是先渲染后备。请帮助我实现这一点。
附:我正在使用服务器端渲染,虽然我认为这没有任何影响
// App component
// I have trimmed a lot of non relevant logic
export const LayoutSetter = createContext((layout: Layout): void => {});
export default class App {
constructor(props: AppProps) {
super(props);
this.state = {
layout: {
columns: "100vw",
rows: "50px 50px",
areas: "
header
content
",
},
};
}
setLayout(layout: Layout): void {
this.setState({ layout: layout });
}
render(): JSX.Element {
const { Component, pageProps } = this.props;
const __NextStyle = createGlobalStyle`
#__next {
display: grid;
grid-template-columns: ${this.state.layout.columns};
grid-template-rows: ${this.state.layout.rows};
grid-template-areas: "${this.state.layout.areas}";
}
`;
const setter = (layout: Layout): void => this.setLayout(layout);
return (
<>
<__NextStyle />
<LayoutSetter.Provider value={setter}>
<Component {...pageProps} />
</LayoutSetter.Provider>
</>
);
}
}
// Child component
const layout: Layout = {
columns: "90vw",
rows: "50px 500px",
areas: `
header
section
`,
};
const Home = (): JSX.Element => {
const setLayout = useContext(LayoutSetter);
useEffect(() => {
setLayout(layout);
}, []);
【问题讨论】:
标签: javascript reactjs typescript next.js styled-components