我使用Webpack 4,Babel 7,React 16.8。当用户加载我的页面时,我的应用程序会加载google网络字体,许多组件所需的外部图像,这些组件会参与初始渲染。
我用这样的sass文件加载字体:
@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,700');
我在所有组件中使用图像,例如:
import SearchSvg from '../../images/search_icon.svg';
并像这样使用它们:
<img src={ SearchSvg } />
现在,我对<img onLoad=.....>
有所了解,并且知道有一些软件包可以测试是否已经加载了网络字体。我的问题是:是否有任何 SYSTEMIC 方法/模式来获取React组件的初始呈现,等到所有这些外部资源被加载?
现在,我将setTimeout
与500 ms
一起使用来延迟index.js
中的根渲染。
setTimeout(function() {
render(
...
);
}, 500);
我希望用一个真正知道何时加载所有内容的东西来替换此硬编码值-理想情况下不必在我使用的每个单个组件中添加代码。
动机当然是为了避免在我最初渲染我的应用程序时出现字体/图像闪烁-由于在图像/字体尚未完全加载时进行渲染。
答案 0 :(得分:3)
您可以在触发onload
事件后渲染根组件。
加载整个页面(包括样式表图像等所有相关资源)后,将触发load事件。 https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
window.onload = function() {
ReactDOM.render(<App/>, document.getElementById('root'));
};
如果您的目的是提高性能,那么我强烈建议您考虑使用服务器端渲染。
答案 1 :(得分:2)
在您的情况下,您可以使用document.fonts.ready
检查字体是否准备好,然后在条件为真时有条件地渲染所需的部分
在此找到一个示例:
https://developer.mozilla.org/en-US/docs/Web/API/Document/fonts
对于您的用例,可以使用上面的链接中提供的类似功能,然后将状态值设置为true(如果就绪)。然后,您可以有条件地渲染想要的内容
例如:
在componentDidMount中调用该函数:
componentDidMount() {
this.isFontLoaded()
}
该函数使用document.fonts.ready,它返回一个Promise。然后,一旦承诺返回,我们便将状态值fontReady
设置为true:
isFontLoaded = () => {
document.fonts.ready.then(this.setState({ fontReady: true }))
}
仅在fontReady
为真时呈现您想要的东西:
{fontReady && <img src={ SearchSvg } />}
答案 2 :(得分:1)
您可以使用包装器组件进行所有检查,并在发生负载以及完成所有操作后显示加载或不显示任何内容,从而呈现应用程序。像这样:
class LoadApplication {
state = { loaded: false }
timer = null
componentDidMount() {
this.timer = setInterval(this.checkStuff, 50)
}
componentWillUnmount() {
clearInterval(this.timer)
}
checkStuff() {
if (stuffIsLoaded) {
this.setState({ loaded: true })
}
}
render() {
return this.state.loaded ? this.props.children : null;
}
}
...
ReactDOM.render(<LoadApplication><App /></LoadApplication>, document.querySelector('#root'))
这有点与CRA处理错误的方式相同。建议使用相同的方法来捕获React documentation中组件中的错误,因此我认为这可能是您正在寻找的。希望对您有所帮助。