componentDidUpdate 不触发

componentDidUpdate does not fire

所以我一直在努力弄清楚 react-redux 生态系统有一段时间了。我快到了,但仍然有一些问题一直给我带来问题,那就是 componentDidUpdate 方法。当我分派异步操作时,store is reducer 被正确调用并且组件的状态确实更新了。

但由于某种原因,componentDidUpdate 方法没有触发,没有重新渲染,我无法访问更新的道具。如果我 console.log(this.props.blogStore),我可以在 devtools 中看到它的变化。起初它显示为一个空对象,但在单击时它会打开并显示更新后的状态。

我尝试了尽可能多的生命周期方法,但似乎没有任何效果,包括 componentWillReceiveProps。

知道我做错了什么吗?

代码如下:

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';

import App from './App';
import Datastore from 'Datastore';

const store = Datastore()

store.subscribe(() => console.log("state changed", store.getState()))

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById('app')
);

Datastore.js

import { combineReducers, createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk'

import Mainmenu from 'reducers/Mainmenu';
import Blogstore from 'reducers/Blogstore';

const reducer = combineReducers({
    Mainmenu,
    Blogstore,
})

export default function Datastore() {
    const store = createStore(
        reducer,
        applyMiddleware(thunk)
    )

    return store
}

减速机

import Article from 'lib/Article';
import { ARTICLE_LOAD, ARTICLE_UPDATE, SAVE_ARTICLE_LIST } from 'actionTypes';

const initialBlogState = {
}

const Blogstore = (state=initialBlogState, action) => {
    switch(action.type) {
        case SAVE_ARTICLE_LIST:
            state.init = true
            state.articles = action.payload
            return state
        case ARTICLE_LOAD:
            return state
        case ARTICLE_UPDATE:
            return state
    }
    return state
}

export default Blogstore;

博客-actions.js

import { ARTICLE_LOAD, ARTICLE_UPDATE, SAVE_ARTICLE_LIST } from 'actionTypes';
import APIFetch from '../lib/Fetch';

export function getArticlePids() {
    return dispatch => {
        APIFetch().get("/blog/list").then(response => {
            dispatch({
                type: SAVE_ARTICLE_LIST,
                payload: response.data
            })
        })
    }
}

分量

import React from 'react';
import { connect } from 'react-redux';
import * as blogActions from '../actions/blog-actions';

@connect(state => ({
    blogStore: state.Blogstore
}))
export default class Blog extends React.Component {
    constructor() {
        super()
    }

    componentDidMount() {
        this.props.dispatch(blogActions.getArticlePids())
    }

    componentDidUpdate(prevProps) {
        console.log("update", prevProps)
    }

    render() {
        console.log("render", this.props.blogStore)

        return (
            <div><h1>Blog</h1></div>
        )

    }
}

差不多就这些了。我不会费心粘贴 index.js 和组件之间的 App 和 Router,因为那里没有任何有趣的东西。只是一个基本的反应路由器和与此无关的组件。

你需要从你的 reducer 中 return 一个新对象,像这样:

import Article from 'lib/Article';
import { ARTICLE_LOAD, ARTICLE_UPDATE, SAVE_ARTICLE_LIST } from 'actionTypes';

const initialBlogState = {
}

const Blogstore = (state=initialBlogState, action) => {
    switch(action.type) {
        case SAVE_ARTICLE_LIST:
            return Object.assign({}, state, {
                init: true,
                articles: action.payload,
            })
        case ARTICLE_LOAD:
            return state
        case ARTICLE_UPDATE:
            return state
    }
    return state
}

export default Blogstore;

否则,如果您尝试直接更新您的状态(正如您目前正在做的那样),它只会改变状态的内部引用,并且 React 组件将无法检测到更改并且不会重新渲染。 Read more here.