Redux 会自动更新它连接的 React 组件吗?

Does Redux update the React component it is connected to automatically?

我的印象是当我的 Redux store 更新时(通过向 reducer 发送一个动作),我的 Provider 应该让新的 store 可用于它的所有 child 组件。因此,当我使用 mapStateToProps() 将容器组件连接到商店时,该组件在收到与商店一起更新的新道具时应该 re-render,而不需要 componentWillReceiveProps()。我这样想错了吗?

在阅读了几个小时的文档和其他堆栈溢出答案之后,我发现有些东西不合我意。我很确定我的 reducer 工作正常并且正在返回一个新的 object,我的组件可以访问商店,并且我的初始状态渲染得很好。如果有人能让我更好地了解事物的流程,我将永远感激不已。

基本上,我有一个 header 组件导入商店,使用 Provider 并呈现一个 "FAQ" 组件:

import React from 'react'; 
import FAQ from './Faq';
import {Provider} from "react-redux";
import  store  from '../store/index'

class Header extends React.Component {
    render() {
        return (
                <Provider store = {store}>
                    <FAQ  />
                </Provider>
        )
    }
}
export default Header;

"FAQ" 组件是一个容器,通过 mapStateToProps() 连接到商店,它导入 "FAQTest" 组件,这是一个将被传递的展示组件 this.state.thisFood作为道具,以便它可以呈现商店中的数据。还有一个 "addFood" 调度我的动作的函数,可以在底部的 mapDispatchToProps() 中看到。

import React from 'react'; 
import {connect} from 'react-redux';
import FAQTest from './faqTest';

class FAQ extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            thisFood: props.breakfast
        };
    }

    //adding this makes the component state update, but I think it should work without it
    componentWillReceiveProps(nextProps){
        this.setState({thisFood: nextProps.breakfast})
    }

    addFood = () => {
        this.props.addFood();
    }

    render() {
                return (

                    <React.Fragment>
                        <button onClick={this.addFood}> Add Food </button> 
                        <FAQTest food = {this.state.thisFood} />
                        </React.Fragment>
                    )
            }
}



const mapStateToProps = function(state) {
    return {
        breakfast: state.faq.breakfast
    }
}

function mapDispatchToProps(dispatch) {
    return {
        addFood: () => dispatch({type: 'ADD_FOOD', food: 'Waffles'})
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(FAQ);

当我单击 "Add Food" 按钮时,由于 mapStateToProps(),我的商店得到更新,我的 FAQ 容器组件的道具也得到更新。我认为这会触发我的 FAQ 组件更新其状态,但是除非我使用 componentWillReceiveProps,否则状态不会更新。这是否按预期工作?

以防万一我做了一些傻事,这是我的减速器:

const initialState = {
    breakfast: ["eggs", "bacon"]
  }

export default function faqReducer(state = initialState, action) {

  switch (action.type) {
    case "ADD_FOOD":
      return Object.assign({}, state, {
        breakfast: [...state.breakfast, action.food]
      })
    default:
      return state;
  }
}

这是我的根减速器和我的 combineReducers() 函数:

import { combineReducers } from "redux";
import faq from './faqReducer'

export default combineReducers({
  faq: faq
});

问题是您正在将数据从 props 复制到状态,但仅在安装组件时才这样做,然后期望状态在新的 props 到达时以某种方式更新。

Copying data from props to state is almost always the wrong approach。请不要那样做。只需使用道具的价值。

另外两条改进代码的建议:

  • 更喜欢使用 the "object shorthand" form of mapDispatch,而不是将其编写为函数
  • 我们建议使用我们新的官方 Redux Starter Kit package 作为编写 Redux 逻辑的标准方式。它包括用于简化几个常见 Redux 用例的实用程序,包括存储设置、定义缩减器、不可变更新逻辑,甚至一次创建整个 "slices" 状态。