【问题标题】:Trying to re-render after store update via redux尝试通过 redux 更新商店后重新渲染
【发布时间】:2018-08-29 18:14:52
【问题描述】:

我正在使用 redux 在 store 中存储菜单数据。

它工作正常,但是一旦我通过调度更新存储,组件不会重新渲染,如果我使用 this.forceUpadate 它可以工作但我不想使用它。有什么解决办法吗?

代码

class MenuContents extends Component {
  constructor() {
    super();  
    this.state = {
      menu : []
    }    
  }
  componentDidMount() {
    // populate the left menu
    fetch("./services/left-menu.json")
    .then(res => res.json())
    .then(data => {
      store.dispatch( addLeftMenu(data))
      this.forceUpdate(); // I dont want to use this
    }).catch(function() {
      console.log("An error occured during fetch operation.");
    });
  }
  render() {
    let storeValue = store.getState();
    const leftMenu = storeValue.leftMenu[0];

    const isMenuLoaded = leftMenu !== undefined && leftMenu !== "";
    let menuContents;
    let menu;

    if(isMenuLoaded) {
        menuContents = leftMenu.map((menuItem, index)=> {

        menu = <li role="presentation" key={index}>
                  <a className="accordion-toggle" data-toggle="accordion" href="#">
                  {menuItem.name}
                  </a>

              </li>;
        return menu;
      }
      );
      menuContents = <ul className="nav nav-pills nav-stacked"> {menuContents} </ul>;
    }
    else {
      menuContents = <Spinner />
    }
    return (<div>{menuContents}</div>);
  }
}

export default MenuContents;

请看下面的reducer代码。

reducer/index.js

import { ADD_LEFT_MENU } from "../constants/action-types";

const initialState = {
  leftMenu: []
};
const rootReducer = (state = initialState, action) => {
  switch (action.type) {
    case ADD_LEFT_MENU:
    return { ...state, leftMenu: [...state.leftMenu, action.payload]};
    default:
      return state;
  }
};
export default rootReducer;

【问题讨论】:

  • 请在此处分享您的减速器代码
  • @SakhiMansoor 请查看更新代码
  • 你在哪里把你的组件和 redux 连接起来了?
  • 我没做过,我只是用store、dispatch和subscribe,不知道怎么用react-redux
  • 你可以将你的 fetch 函数移动到一个 redux 动作中,这样更符合逻辑

标签: reactjs redux react-redux


【解决方案1】:

我想脱离 Sakhi Mansoor 所说的,你想将你的组件连接到 redux 商店。这是一篇我认为解释得很好的文章:

https://medium.com/mofed/reduxs-mysterious-connect-function-526efe1122e4

当组件的状态或道具发生变化时,基本上会重新渲染组件。现在你有一个组件,你有一个商店。需要发生的是,您将触发一些操作,这些操作将返回一些内容以供减速器使用。 reducer 将更新 redux 存储。理想情况下,store 会更新组件的 props,然后触发重新渲染。

我认为你缺少的是最后一部分。当你像他们在文章中那样调用 connect 时,它会将 store 连接到组件。所以每当 store 的某些部分发生变化时,它都会更新组件中相关的 props。

【讨论】:

    【解决方案2】:

    如果你的 fetch 调用没有改变组件的 props 或状态,React 就无法知道你的组件需要重新渲染。您应该将您的组件与 react-redux 连接起来。直接在组件中访问 redux 存储并不是通常的做法,不建议这样做。大多数生态系统都是围绕连接的组件构建的。

    【讨论】:

      【解决方案3】:
      import { connect } from 'react-redux';
      import { bindActionCreators } from 'redux';
      
      class MenuContents extends Component {
        constructor() {
          super();  
          this.state = {
            menu : []
          }    
        }
        componentDidMount() {
          // populate the left menu
          fetch("./services/left-menu.json")
          .then(res => res.json())
          .then(data => {
            store.dispatch( addLeftMenu(data))
          }).catch(function() {
            console.log("An error occured during fetch operation.");
          });
        }
        render() {
          let storeValue = store.getState();
          const leftMenu = storeValue.leftMenu[0];
      
          const isMenuLoaded = leftMenu !== undefined && leftMenu !== "";
          let menuContents;
          let menu;
      
          if(isMenuLoaded) {
              menuContents = leftMenu.map((menuItem, index)=> {
      
              menu = <li role="presentation" key={index}>
                        <a className="accordion-toggle" data-toggle="accordion" href="#">
                        {menuItem.name}
                        </a>
      
                    </li>;
              return menu;
            }
            );
            menuContents = <ul className="nav nav-pills nav-stacked"> {menuContents} </ul>;
          }
          else {
            menuContents = <Spinner />
          }
          return (<div>{menuContents}</div>);
        }
      }
      
      const mapStateToProps = state => ({
         leftMenu: state.leftMenu,
      });
      
      const mapDispatchToProps = dispatch => ({
         addLeftMenu: bindActionCreators(addLeftMenu, dispatch),
      });
      
      
      export default connect(mapStateToProps, mapDispatchToProps)(MenuContents);
      

      【讨论】:

      • 这里需要mapDispatchToProps吗? +1
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-04
      • 1970-01-01
      • 1970-01-01
      • 2021-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多