Почему этот компонент (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]);
→ Ссылка