首页 > 解决方案 > 还原 | 子组件不会重新渲染父组件

问题描述

代码很长,但想法是这样的:

我有 3 个组件 Base App 组件, MapComponent , ShipComponent

App 组件使用容器调用 MapComponent,MapComponent 调用 ShipComponent 也使用容器。Map 和 Ship 容器都连接到 store。Map 和 Ship 组件使用相同的多数组数据并传递给mapStateToProps

在使用 useEffect() 的组件 Ship 中,调用一个动作来生成数据并将其放入存储中。

问题:

子组件(组件 Ship)重新渲染得很好,但组件 Map(父组件)甚至不使用父 Map 组件也使用相同的 shipLocation 数组。map 和 Ship 组件都从同一个 redux 存储中获取它。

为什么执行动作后子组件会重新渲染而父组件不会?我如何解决它?

作为测试,我没有将动作传递mapDispatchToProps给 ShipComponent,而是将其传递给 MapComponent,然后通过 props 将其传递给 ShipComponent 以使其执行。只有这样它才更新了父 MapComponent。但我需要 ShipComponent 来获取操作并更新 MapComponent。

编辑添加的代码示例:

所以根组件(App)

import React from "react";
import { Provider } from "react-redux";
import Map from "../containers/Map";
import mainStore from "../store";

const store = mainStore();

function AppComponent(props) {
  return (
    <Provider store={store}>
      <Map />
    </Provider>
  );
}

export default AppComponent;

调用容器 Map 将所有状态数据从存储传递到组件 MapComponent

import { connect } from "react-redux";
import MapComponent from "../components/MapComponent";

const mapStateToProps = ({ shipR }) => {
  return {
    shipLocation: [...shipR.shipLocation],
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
  };
};

const Map = connect(mapStateToProps, mapDispatchToProps)(MapComponent);

export default Map;

地图组件:

import React from "react";
import { Provider } from "react-redux";
import mainStore from "../store";
import Ship from "../containers/Ship";

const store = mainStore();

function MapComponent(props) {
  return (
    <div id="__Map__">
          {
            <Provider store={store}>
              <Ship />
            </Provider>
          }
    </div>
  );
}

export default MapComponent;

这个 MapComponent 调用 ShipComponent 容器

import { connect } from "react-redux";
import ShipComponent from "../components/ShipComponent";
import { generateDefaultShips, shipToggle } from "../actions/shipAction";

const mapStateToProps = ({ shipR }) => {
  return {
    shipLocation: [...shipR.shipLocation],
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    genShips() {
      dispatch(generateDefaultShips());
    },
  };
};

const Ship = connect(mapStateToProps, mapDispatchToProps)(ShipComponent);

export default Ship;

ShipComponent 组件如下所示:

import React, { useEffect } from "react";

function ShipComponent(props) {
  useEffect(() => {
    props.genShips();
  }, []);
  return (
    <div className="ship"></div>
  );
}

export default ShipComponent;

genShips()是一个动作:

import { SHIP_GENERATION_RESULT } from "../constants";

export function generateDefaultShips() {
  let arr = [];
  for (let x = 0; x < 7; x++) {
    arr[x] = [];
    for (let y = 0; y < 11; y++) arr[x][y] = null;
  }
  return { type: SHIP_GENERATION_RESULT, ships: arr };
}

MapComponent 减速器:

const initiateState = {
};

function mapReducer(state = initiateState, action) {
  return state;
}

export default mapReducer;

和 ShipComponent 减速器:

import {
  SHIP_GENERATION_RESULT,
} from "../constants";

const initiateState = {
  shipLocation: [],
};

function shipReducer(state = initiateState, action) {
  switch (action.type) {
    case SHIP_GENERATION_RESULT: {
      return {
        ...state,
        shipLocation: action.ships,
      };
    }
    default:
      return state;
  }
}

export default shipReducer;

和常量 index.js 包含: export const SHIP_GENERATION_RESULT = "SHIP_GENERATION_RESULT";

所有这些容器、常量、组件和操作都在不同的文件中

ps 子组件 ShipComponent 可以很好地获取 shipLocation 多数组数据,但是由于 MapComponent(父级)不会重新渲染,因此他不会。

O 和 reduxers index.js:

import { combineReducers } from "redux";
import mapReducer from "./mapReducer";
import shipReducer from "./shipReducer";

const allReducers = combineReducers({
  mapR: mapReducer,
  shipR: shipReducer,
});

export default allReducers;

存储 index.js:

import { createStore, applyMiddleware } from "redux";
import thunkMiddleware from "redux-thunk";
import allReducers from "../reducers";
import { composeWithDevTools } from "redux-devtools-extension";

export default function mainStore(prevState) {
  return createStore(
    allReducers,
    prevState,
    composeWithDevTools(applyMiddleware(thunkMiddleware))
  );
}

标签: reactjsredux

解决方案


您正在为 App 和 Map 组件使用不同的商店,应该帮助删除商店及其在 MapComponent 中的提供者。所有应用程序中应该只有 1 个 redux 存储,以使所有数据保持一致。


推荐阅读