将Redux存储状态传递给ReactJS中子组件的正确方法

时间:2019-06-27 18:41:18

标签: reactjs redux

==已编辑问题,因为不幸的是解决方案无法正常工作!==

==我现在意识到这是因为我的Redux Store无法正确更新!==

我正在尝试使用Redux在ReactJS中构建一个项目,该项目具有Redux存储,并通过Axios提取定期更新状态。

此Axios提取操作可​​以很好地更新初始存储状态。

我将存储状态作为对Parent的Child元素的支持。

当商店的状态发生变化时,如果一个孩子受到影响,我需要道具传递下来并重新渲染该孩子。

我曾想过,如果我将道具(由mapStateToProps设置)发送给了孩子,并且状态发生了变化,这将重新发送道具并导致重新渲染,但事实并非如此。 / p>

对于实现我正在尝试的正确方法的任何建议,将不胜感激。

我已经从Parent元素的componentDidMount方法中记录了道具,并且我看到了道具的更新,正如我所期望的那样;每次我手动更改要获取的JSON时,都会更改道具以反映这一点。

父元素:

class Parent extends React.Component {

    componentDidMount() {
        this.props.updatePanels();
        console.log(this.props);
        this.interval = setInterval(() => {
        this.props.updatePanels();
        }, 5000);
       }

     componentWillUnmount() {
       clearInterval(this.interval)
     }

     renderList() {
        return this.props.panels.map((panel) => {
          return (
              <Child key={panel.id} lat={panel.lat} lng={panel.lng} />
          );
        });
      }

    render() {
        return (
            <div>
                {this.renderList()}
            </div>

        );
    }
}

子元素:

const Child = props => (
    <div key={props.id}>
         <div>{props.lat}</div>
         <div>{props.lng}</div>
    </div>
)

Redux Action Creator

import panelFetch from '../dataCalls/panelFetch';

export const updatePanels = () => {

    return async (dispatch) => {
      const response = await panelFetch.get("/panelList.json");

      console.log(response.data);

      dispatch ({
        type: 'UPDATE_PANELS',
        payload: response.data
      });
    };
  };

Redux Update Panels Reducer

export default (state = [], action) => {

    switch (action.type) {
      case 'UPDATE_PANELS':
        return action.payload;
      default:
        return state;
    }

  };

Redux Reducers

import { combineReducers } from 'redux';
import updatePanelsReducer from './updatePanelsReducer'; //compartmentalise our reducer

const panelReducer = () => {
    return [{
        "id": 400016,
        "lat": 51.509865,
        "lng": -0.118092
    }, {
        "id": 400017,
        "lat": 51.509865,
        "lng": -0.118092
    }, {
        "id": 400018,
        "lat": 51.509865,
        "lng": -0.118092
    }, {
        "id": 400019,
        "lat": 51.509865,
        "lng": -0.118092
    }
];
};

export default combineReducers({
    panels: panelReducer,
    updatePanels: updatePanelsReducer
  });

2 个答案:

答案 0 :(得分:1)

子组件不应将其道具置于其状态。

子组件不会更新,因为其渲染方法不依赖于其道具,而是依赖于其自身的内部状态,您可以在其构造函数中对其进行一次设置,而永远不会更改。

如果您的子组件如下所示,它将起作用:

class Child extends React.Component {
    constructor(props) {
        super(props)
    }

    render() {
        return (
            <div key={this.props.id}>
                 <div>{this.props.lat}</div>
                <div>{this.props.lng}</div>
            </div>
        )
    }
}

此外,您可能要考虑摆脱类组件的所有样板,尤其是在仅使用其render方法的情况下。您可以像这样将其重写为功能组件:

const Child = props => (
    <div key={props.id}>
         <div>{props.lat}</div>
         <div>{props.lng}</div>
    </div>
)

答案 1 :(得分:0)

问题在于,最初在构造函数中只设置了一次Child组件的状态。道具的后续更改不会更新Child组件的状态。

您可以使用React的getDerivedStateFromProps(props, state)方法设置初始状态,然后在道具更新后更新状态。在这里阅读 https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops

OR

您只需将道具传递给Child组件,而不必设置状态。

class Child extends React.Component {
    constructor(props) {
        super(props)
    }

    render() {
        return (
            <div key={this.props.id}>
                 <div>{this.props.lat}</div>
                <div>{this.props.lng}</div>
            </div>
        )
    }
}

希望这会有所帮助!

相关问题