最新消息:VPS服务器又从fzhost.net换回Linode了,主题仍用朋友推荐的大前端D8

【规避解决】ReacJS中用redux方式更新数据导致数据没有及时更新

ReactJS crifan 766浏览 0评论

现在遇到的现象是:

Preact的项目中,之前别人写的代码,用redux的方式去更新数据的。

比如首页,相关代码如下:

/src/container/main/index.js

export default class Main extends Component {
  fetchTodoNum() {
    console.log("Main render");
    this.props.fetch(‘/index/index/TodoNum’, {}, (data) => {
       const {
        faqing_num = 0,
        peizhong_num = 0,
        yunjian_num: {
          fujian_num = 0,
          chujian_num = 0
        },
        yichang_num = 0
      } = data;
      this.props.updateMainEntryNums([
        faqing_num,
        peizhong_num,
        fujian_num + chujian_num,
        yichang_num
      ]);
  }
  render() {
    console.log("Main render");
    const curYearMonthStr = (new Date()).Format("yyyy年MM月");
    const {
      mainEntries,
      mainRings,
      mainCowStatus
    } = this.props;
    return (
      <div class={style.container}>
。。。
        <GradientBar data={mainEntries} />
  }
}

然后对应的页面中,

对于路径/匹配到Main的路由”/“而加载了Main后,

结果Main页面的数据还是空的,没有加载:

然后,只有再次点击首页后,继续加载Main,然后出发了render函数,所以数据才会更新:

对应着内部的,Main的render中,从this.props中获得更新后的数据,然后才能刷新显示出来。

并且,这个数据没有及时更新的问题,在之前的切换农场后,重新刷新数据时,也是没有刷新,也是同样的问题。

和这个同样的问题还有

底部的tab,在路由已经切换到其他页面后,比如从首页切换到个人中心后,结果地步tab的个人中心的图片还是没有变高亮的蓝色,还是没有刷新

需要再次点击一次,才能刷新。

所以此处的问题是:

此处Preact中,通过redux的方式去更新数据,但是由于从parent过来的props的数据虽然变化了,但是页面却没有(调用render去)刷新

但是记得是:

如果parent传递过来的props有变化,则也会更新对应的数据的

此处之所以没有更新, 可能是由于:

数据统一都放到了:

/src/store/store.js

let ACTIONS = {
  UPDATE_MAIN_ENTRY_NUM: ({mainEntries, …state}, { nums }) => {
    mainEntries.forEach((e, i) => {
      e.number = nums[i];
    });
    return {
      mainEntries,
      …state
    };
  },
}
const INITIAL = {
  // 主页的渐变色块
  mainEntries: [{
    text: ‘发情管理’,
    number: 0,
    href: ‘/estrusManagement’
  },。。。}],
};
export default createStore((state, action) => (
  action && ACTIONS[action.type] ? ACTIONS[action.type](state, action) : state
), INITIAL, window.devToolsExtension && window.devToolsExtension());

好像是:

把此处的INITIAL,传递到了每个页面,是的

this.props都可以访问到对应的数据

但是对应的数据,变动后

(虽然调用到了对应的函数:

),却无法及时通知对应的子页面去刷新页面显示。

react router redux not updating

react redux not update view

Container and components not re-rendering upon successful action dispatch · Issue #1159 · reactjs/redux

Eventwhen: next button · Issue #40 · DRDD2016/app

Updating Redux state does not trigger componentWillReceiveProps – Stack Overflow

javascript – React-redux store updates but React does not – Stack Overflow

Components not re-rendering with connect() · Issue #585 · reactjs/redux

感觉是:

要么是此处使用redux没有使用好,要么是本身preact-redux有bug

目前看来,虽然可能像是前者,但是此处的

返回更新后的state

这个做法,此处的写法:

  UPDATE_MAIN_ENTRY_NUM: ({mainEntries, …state}, { nums }) => {
    mainEntries.forEach((e, i) => {
      e.number = nums[i];
    });
    return {
      mainEntries,
      …state
    };
  },

看起来是对的。

目前没时间去深入研究了。

抽空再去找原因吧。

【总结】

无奈的最后只能手动去改为,正常的数据更新方式:

把数据的变化,放到state中去,这样如果数据变化,setState后,数据就会刷新显示了:

代码:

export default class Main extends Component {
  state = {
    // todoNumDict : {
    //   faqing_num :0,
    //   peizhong_num : 0,
    //   yunjian_num : {
    //     fujian_num : 0,
    //     chujian_num : 0
    //   },
    //   yichang_num : 0
    // },
    todoNumList : [0, 0, 0, 0],
}
  fetchTodoNum() {
    console.log("Main render");
    this.props.fetch(‘/index/index/TodoNum’, {}, (data) => {
      // const {
      //   faqing_num = 0,
      //   peizhong_num = 0,
      //   yunjian_num: {
      //     fujian_num = 0,
      //     chujian_num = 0
      //   },
      //   yichang_num = 0
      // } = data;
      // this.props.updateMainEntryNums([
      //   faqing_num,
      //   peizhong_num,
      //   fujian_num + chujian_num,
      //   yichang_num
      // ]);
      console.log(JSON.stringify(data));
      // this.setState({todoNumDict : data});
      // console.log(JSON.stringify(this.state.todoNumDict));
      this.setState({
        todoNumList : [
          data.faqing_num,
          data.peizhong_num,
          data.yunjian_num.chujian_num + data.yunjian_num.fujian_num,
          data.yichang_num
        ]
      });
      console.log(JSON.stringify(this.state.todoNumList));
    });
  }
  render() {
    console.log("Main render");
    const {
      mainEntries,
    } = this.props;
    let newMainEntries = mainEntries;
    this.state.todoNumList.forEach((item, curIdx) => {
      newMainEntries[curIdx].number = item;
    });
    console.log(`newMainEntries=${JSON.stringify(newMainEntries)}`);
    return (
      <div class={style.container}>
       …
        <GradientBar data={newMainEntries} />

效果:

后续有空再深究。

转载请注明:在路上 » 【规避解决】ReacJS中用redux方式更新数据导致数据没有及时更新

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
14 queries in 0.217 seconds, using 10.27MB memory