我有一个应用程序,例如Unsplash。当我想顶照片时,在将照片重新渲染到照片列表时遇到问题。我想让照片按一下就不会重新渲染图像,只是 返回点赞和Liked_by_user的数目:true或false。这是我的网站mishindmitry.site。 https://github.com/mishindmitry95/jsDiploma-这是我的存储库
action.js
export function likePhoto(json, id) {
return {
type: LIKE_PHOTO,
payload: json,
id
};
}
export function likePhotoRequest(id) {
return {
type: LIKE_PHOTO_REQUEST,
id
};
}
export function unlikePhoto(json, id) {
return {
type: UNLIKE_PHOTO,
payload: json,
id
};
}
export function unlikePhotoRequest(id) {
return {
type: UNLIKE_PHOTO_REQUEST,
id
};
}
export function getLikeToPhoto(id) {
return dispatch => {
dispatch(likePhotoRequest(id));
return unsplash.photos
.likePhoto(id)
.then(toJson)
.then(json => {
dispatch(likePhoto(json, id));
});
};
}
export function getUnlikeToPhoto(id) {
return dispatch => {
dispatch(unlikePhotoRequest(id));
return unsplash.photos
.unlikePhoto(id)
.then(toJson)
.then(json => {
dispatch(unlikePhoto(json, id));
});
};
}
reducer.js
const initialState = {
isFetching: false,
error: false,
photos: []
};
function photos(state = initialState, action) {
switch (action.type) {
case LIKE_PHOTO:
return {
...state,
isFetching: false,
photo: {...state.photo, ... action.payload.photo},
photos: state.photos.map(photo => {
if (photo.id === action.id) {
return {
...photo,
...action.payload.photo
};
} else {
return photo;
}
})
};
case LIKE_PHOTO_REQUEST: {
return {
...state,
id: action.id,
isFetching: true,
};
}
case UNLIKE_PHOTO:
return {
photos: state.photos.map(photo => {
if (photo.id === action.id) {
return {
...photo,
...action.payload.photo
};
} else {
return photo;
}
})
};
case UNLIKE_PHOTO_REQUEST: {
return {
...state,
photo: action.payload,
id: action.id,
isFetching: true
};
}
export default photos;
照片列表.js
export default class PhotosList extends PureComponent {
constructor(props) {
super(props);
this.handleScroll = this.handleScroll.bind(this);
}
componentDidMount() {
window.addEventListener("scroll", this.handleScroll);
}
componentWillUnmount() {
window.removeEventListener("scroll", this.handleScroll);
}
handleScroll() {
const { photos, getPhotos } = this.props;
const windowHeight = window.innerHeight;
const scrollTop = window.scrollY;
const clientHeight = document.body.clientHeight;
const scrollOnBottom = clientHeight - scrollTop;
if (windowHeight - scrollOnBottom === 0) {
return this.props.getPhotos(this.props.photos);
}
}
render() {
const options = {
year: "numeric",
month: "long",
day: "numeric"
};
return (
<div className="photolist-container">
<ul className="flex-container">
{this.props.photos.map((photo, id) => (
<li key={id}>
<div className="item_container">
<Link to={`/photo/${photo.id}`}>
<img src={photo.urls.regular} alt="photo" key={id} height="350px" width="100%"/>
</Link>
<div className="info-container">
<div className="date_container">
{new Date(photo.created_at).toLocaleString("ru", options)}
</div>
<div className="container__btn_like">
{photo.liked_by_user ? (
<button
className="btn_like__clicked"
onClick={() => this.props.getUnlikeToPhoto(photo.id)}
>
<svg
className="svg_img"
version="1.1"
viewBox="0 0 32 32"
width="16"
height="16"
aria-hidden="false"
>
<path d="M17.4 29c-.8.8-2 .8-2.8 0l-12.3-12.8c-3.1-3.1-3.1-8.2 0-11.4 3.1-3.1 8.2-3.1 11.3 0l2.4 2.8 2.3-2.8c3.1-3.1 8.2-3.1 11.3 0 3.1 3.1 3.1 8.2 0 11.4l-12.2 12.8z"></path>
</svg>
</button>
) : (
<button
className="btn_like"
onClick={() => this.props.getLikeToPhoto(photo.id)}
>
<svg
className="svg_img"
version="1.1"
viewBox="0 0 32 32"
width="16"
height="16"
aria-hidden="false"
>
<path d="M17.4 29c-.8.8-2 .8-2.8 0l-12.3-12.8c-3.1-3.1-3.1-8.2 0-11.4 3.1-3.1 8.2-3.1 11.3 0l2.4 2.8 2.3-2.8c3.1-3.1 8.2-3.1 11.3 0 3.1 3.1 3.1 8.2 0 11.4l-12.2 12.8z"></path>
</svg>
</button>
)}
{" " + photo.likes}
</div>
<div className="user_photo_name">
<a href={photo.user.links.html} className="user_link">
<img
src={photo.user.profile_image.small}
className="user_img"
/>
<h3 className="user_name">{photo.user.name}</h3>
</a>
</div>
</div>
</div>
</li>
))}
</ul>
<button className="loadphoto_btn" onClick={this.props.getPhotos}>
Загрузить еще
</button>
</div>
);
}
}