Почему этот компонент (home.js) вызывается дважды, несмотря на то, что я написал React.memo
// ACTION
import axios from "axios";
import {API} from "../../constants";
import * as type from "../types";
function error() {
return new Error("Error from server");
}
// GET List all posts
export const get_listAllPosts = () => async (dispatch) => {
try {
const res = await axios.get(API._get)
.then(res => res.data);
dispatch(dispatchListAllPosts(res));
} catch (e) {
error()
}
};
export const dispatchListAllPosts = (posts) => ({
type: type.GET_POSTS,
posts
});
// REDUCER
import * as type from "../types";
const initialState = {
posts: []
};
export default function (state = initialState, action) {
switch (action.type) {
case type.GET_POSTS:
return {
...state,
posts: action.posts
};
default:
return state;
}
}
// COMPONENT
import React, {useEffect} from 'react';
import blogImage from "../images/blog.jpg";
import {connect} from "react-redux";
import {del_deletePost, get_listAllPosts} from "../redux/actions/postAction";
import {getData, getLoading} from "../redux/selectors";
const Home = React.memo(({posts, get_listAllPosts, del_deletePost, history}) => {
console.log("render"); // вызывается дважды
useEffect(() => {
get_listAllPosts()
}, [get_listAllPosts]);
function handleDeletePost(id) {
const remove = window.confirm("Are you sure delete the post: " + id);
if (remove) {
del_deletePost(id)
}
}
return (
<main role="main">
<section className="jumbotron text-center mb-0">
<div className="container">
<h1>Blog</h1>
</div>
</section>
<div className="album py-5 bg-light">
<div className="container">
<div className="row">
{
posts && posts.map(post => {
return (
<div className="col-md-4" key={post.id}>
<div className="card mb-4 shadow-sm">
<img src={blogImage} alt="" style={{width: "100%", height: "250px"}}/>
<div className="card-body">
<h5 className="card-title">{post.title}</h5>
<p className="card-text">{post.body}</p>
<div className="d-flex justify-content-between align-items-center">
<div className="btn-group">
<button
type="button"
className="btn btn-sm btn-outline-success"
onClick={() => history.push(`/post/${post.id}`)}
>View
</button>
<button
type="button"
className="btn btn-sm btn-outline-primary"
onClick={() => history.push(`/edit/${post.id}`)}
>
Edit
</button>
<button
type="button"
className="btn btn-sm btn-outline-danger"
onClick={() => handleDeletePost(post.id)}
>
Delete
</button>
</div>
</div>
</div>
</div>
</div>
)
})
}
</div>
</div>
</div>
</main>
);
});
function mapStateToProps(state) {
return {
posts: getData(state)
}
}
export default connect(mapStateToProps, {get_listAllPosts, del_deletePost})(Home);
Ответы (1 шт):
Автор решения: Избыток Сусликов
→ Ссылка
Memo это не значит что твой компонент никогда не будет рендерится.
В документации написанно
React.memo — это компонент высшего порядка. Он похож на React.PureComponent, но предназначен для функциональных компонентов.
То есть точно также как работает PureComponent.Если один из пропсов либо состояние компонента не изменяется то компонент не рендерится.В вашем случае проблема в пропсах.
У вас даже useEffect есть который слушает изменения определенного пропса.
useEffect(() => {
get_listAllPosts()
}, [get_listAllPosts]);