首页 > 解决方案 > ReactJS,componentWillReceiveProps可以获取数据,但是render不能

问题描述

我正在使用 sagas 开发一个 ReactJS 15 项目,并重新选择作为中间件来获取数据。我可以成功获取componentWillReceiveProps中的数据并将数据设置为状态,但是当我从状态中获取数据时,渲染函数中仍然没有数据首先运行。有人知道这里发生了什么吗?顺便说一句,我使用json-server 作为模拟数据服务器。下面是我的代码的一部分:

零件:

 constructor(props) {
    super(props);
    this.state = {
      timelineData: [],
    };
  }

  componentDidMount() {
    // use react redux to make the api call here
    this.props.fetchTimelineData({
      id: parse(this.props.location.search.substr(1)).id,
    });
  }
 componentWillReceiveProps(nextProps) {
    console.log('nextProps', nextProps);
    // Successfully take the data from the nextProps (timelineData is not [])
    const { timelineData } = nextProps;
    this.setState({
      timelineData,
    });
  }

render() {
    // the first render called timelineData is an empty array, which will not able to populate the UI
    // which RaiseTimeline is empty
    const { timelineData } = this.state;
    return (
      <RaiseTimelineStyled>
        <RaiseDetailsGrid>
          <Accordion
            title={
              <RaiseAccordionHeader image={image} title={'Timeline'} />
          }>
            <Timeline.wrapper>
              <RaiseTimelineStyled.divider>
                <RaiseTimelineStyled.container>
                  <RaiseTimeline timelineEvents={timelineData} />

action.js(工作正常):

export const setTimelineData = timelineData => console.log('actions.js', timelineData) || ({
  type: ACTIONS.SET_TIMELINE_DATA,
  timelineData,
});

Api.js(工作正常):

class TimelineAPI {
  // payload will be used after backend done
  static fetchTimelineData(payload) {
    return http.get(`${baseURI}/timeline`).then(result => console.log('api', result.data) || result.data);
  }
}

减速机:(工作正常)

function TimelineDataReducer(state = initialState, action) {
  switch (action.type) {
    case ACTIONS.SET_TIMELINE_DATA:
      console.log('reducer', action.timelineData);
      return state.set('numbers', action.timelineData);
    default:
      return state;
  }
}

萨加斯:(工作正常)

export function* fetchTimelineData(action) {
  yield put(togglePendingScreen(true));

  const { result, error } = yield call(TimelineAPI.fetchTimelineData, action.payload);

  if (error) {
    yield put(
      toggleErrorModal({
        isOpen: true,
        text: error.code,
        source: 'Fetch Timeline Data',
      }),
    );
  } else {
    console.log('Sagas', result.timeline);
    yield put(ACTIONS.setTimelineData(result.timeline));
  }
  yield put(togglePendingScreen(false));
}

选择器(工作正常):

import { createSelector } from 'reselect';

const selectTimelineData = state => state.get('TimelinePageData').toJS();

const selectTimeline = () =>
  createSelector(selectTimelineData, TimelineDataState => TimelineDataState.numbers);

export { selectTimeline };

标签: reactjs

解决方案


对我来说,第一次运行时没有数据似乎是合乎逻辑的。

原因是在 react 生命周期中,在 componentDidMount() 之前调用了一次 render() 函数。(V15)

在这里查看 react 15 生命周期:https ://gist.github.com/bvaughn/923dffb2cd9504ee440791fade8db5f9


推荐阅读