使用 React 和 Redux 异步加载图像
Async Image Load with React and Redux
我正在尝试创建一个带有 <PostList />
容器的简单消息墙,该容器显示 <Post />
组件列表。
{posts.map(function (post: any) {
return <Post key={post.postid} post={post} />;
})}
我将单个 post 传递给 Post
组件,该组件有一个 <Avatar />
组件显示其中的用户 profile_pic 否则它会显示一个微调器。
我的问题是如何让组件显示在屏幕上,并在加载图像后用检索到的图像替换微调器?
我目前有以下 Reducers 和 Actions:
用户减速器:
export default function(state = INITIAL_STATE, action : any){
switch(action.type){
case FETCH_USER_LOADING:
return Object.assign({}, state, {isLoading: true});
case FETCH_USER_DONE:
return Object.assign({}, state, {users: state.users.concat(action.payload)});
}
return state;
}
用户操作:
export function fetchUser(id: any) {
return function (dispatch: any) {
dispatch({ type: FETCH_USER_LOADING });
return axios.get(`${ROOT_URL}/users/${id}`, {
headers: { token: localStorage.getItem('token') }
})
.then(function (response) {
dispatch({type: FETCH_USER_DONE, payload: response.data});
return response.data
})
}
}
有很多方法可以做到。
其中之一是编写自己的组件,其中,新加载的图像会在componentDidMount
中提示重绘。这是您可以在自己的项目中使用的惰性图像的完整源代码:
export default class LazyImage extends React.Component {
constructor(props) {
super(props);
this.state = {
loaded: false,
error: false
};
}
componentDidMount() {
const img = new Image();
img.onload = () => {
this.setState({
loaded: true
});
};
img.onerror = () => {
this.setState({
error: true
});
};
img.src = this.props.src;
}
render() {
if (this.state.error) {
return <img
className={this.props.className}
style={this.props.style}
src={this.props.unloadedSrc}
alt={this.props.alt} />
} else if (!this.state.loaded) {
return <img
className={this.props.className}
style={this.props.style}
src={this.props.unloadedSrc}
alt={this.props.alt} />
}
return <img
className={this.props.className}
style={this.props.style}
src={this.props.src}
alt={this.props.alt} />
}
}
然后你会像这样使用:
<LazyImage unloadedSrc={unloadedSrc} src={src} />
然后,您可以选择使用大量组件,您只需通过谷歌搜索条款即可找到这些组件:
- "image load react"
- "react image lazy load"
或任何类似的搜索词变体。我最喜欢的组件是 react-imageloader
.
希望对您有所帮助。
我创建了一个用于延迟加载图像的库。它的主要功能是提供动态调整图像大小,但它也可以解决您的问题。
https://github.com/peterlazzarino/react-adaptive-image
这是一个可用于延迟图像加载的示例,它将解析来自 imgur 的图像。在我的生产应用程序中,我的图像解析器指向图像服务器,但这是完全可定制的。您只需要将 .header-image class 设置为具有高度和宽度即可。
import React from 'react';
import ReactDOM from 'react-dom';
import { initImages } from 'react-adaptive-image';
import AdaptiveImage from 'react-adaptive-image';
initImages({
imageResolver: function(image){
return `https://i.imgur.com/${image.fileName}`
}
})
class App extends React.Component {
render() {
return (
<AdaptiveImage backgroundImage className="header-image" fileName={'U6zWkcZ.png'} />
);
}
}
ReactDOM.render(<App />, document.getElementById('react-root'));
我正在尝试创建一个带有 <PostList />
容器的简单消息墙,该容器显示 <Post />
组件列表。
{posts.map(function (post: any) {
return <Post key={post.postid} post={post} />;
})}
我将单个 post 传递给 Post
组件,该组件有一个 <Avatar />
组件显示其中的用户 profile_pic 否则它会显示一个微调器。
我的问题是如何让组件显示在屏幕上,并在加载图像后用检索到的图像替换微调器?
我目前有以下 Reducers 和 Actions:
用户减速器:
export default function(state = INITIAL_STATE, action : any){
switch(action.type){
case FETCH_USER_LOADING:
return Object.assign({}, state, {isLoading: true});
case FETCH_USER_DONE:
return Object.assign({}, state, {users: state.users.concat(action.payload)});
}
return state;
}
用户操作:
export function fetchUser(id: any) {
return function (dispatch: any) {
dispatch({ type: FETCH_USER_LOADING });
return axios.get(`${ROOT_URL}/users/${id}`, {
headers: { token: localStorage.getItem('token') }
})
.then(function (response) {
dispatch({type: FETCH_USER_DONE, payload: response.data});
return response.data
})
}
}
有很多方法可以做到。
其中之一是编写自己的组件,其中,新加载的图像会在componentDidMount
中提示重绘。这是您可以在自己的项目中使用的惰性图像的完整源代码:
export default class LazyImage extends React.Component {
constructor(props) {
super(props);
this.state = {
loaded: false,
error: false
};
}
componentDidMount() {
const img = new Image();
img.onload = () => {
this.setState({
loaded: true
});
};
img.onerror = () => {
this.setState({
error: true
});
};
img.src = this.props.src;
}
render() {
if (this.state.error) {
return <img
className={this.props.className}
style={this.props.style}
src={this.props.unloadedSrc}
alt={this.props.alt} />
} else if (!this.state.loaded) {
return <img
className={this.props.className}
style={this.props.style}
src={this.props.unloadedSrc}
alt={this.props.alt} />
}
return <img
className={this.props.className}
style={this.props.style}
src={this.props.src}
alt={this.props.alt} />
}
}
然后你会像这样使用:
<LazyImage unloadedSrc={unloadedSrc} src={src} />
然后,您可以选择使用大量组件,您只需通过谷歌搜索条款即可找到这些组件:
- "image load react"
- "react image lazy load"
或任何类似的搜索词变体。我最喜欢的组件是 react-imageloader
.
希望对您有所帮助。
我创建了一个用于延迟加载图像的库。它的主要功能是提供动态调整图像大小,但它也可以解决您的问题。
https://github.com/peterlazzarino/react-adaptive-image
这是一个可用于延迟图像加载的示例,它将解析来自 imgur 的图像。在我的生产应用程序中,我的图像解析器指向图像服务器,但这是完全可定制的。您只需要将 .header-image class 设置为具有高度和宽度即可。
import React from 'react';
import ReactDOM from 'react-dom';
import { initImages } from 'react-adaptive-image';
import AdaptiveImage from 'react-adaptive-image';
initImages({
imageResolver: function(image){
return `https://i.imgur.com/${image.fileName}`
}
})
class App extends React.Component {
render() {
return (
<AdaptiveImage backgroundImage className="header-image" fileName={'U6zWkcZ.png'} />
);
}
}
ReactDOM.render(<App />, document.getElementById('react-root'));