0

I want to load data from api based on router params in component,

The channel page behave as expected when I first open the page, but if I go to other channel page by clicking, ChannelPage component didn't call componentDidMount, but reducer received FETCH_MESSAGES action, the Sidebar component also have the problem. redux-devtools can only received LOCATION_CHANGE action when other channel page get clicked. it's too weird!

What's the best practice for loading data based on params in react component?

Sidebar

class Sidebar extends React.Component {
  componentDidMount() {
    this.props.fetchChannels(1);
  }

  openChannelPage = (e, url) => {
    e.preventDefault();
    console.log('open channel page');
    this.props.changeRoute(url);
  };

  render() {
    let channelsContent = null;

    if (this.props.channels !== false) {
      channelsContent = this.props.channels.map((item, index) => (
        <ChannelItem
          routeParams={this.props.params} item={item} key={`item-${index}`} href={item.url}
          handleRoute={(e) => this.openChannelPage(e, item.url)}
        />
      ), this);
    }

    return (
      <div id="direct_messages">
        <h2 className={styles.channels_header}>messages</h2>
        <ul>
          {channelsContent}
        </ul>
      </div>
    );
  }
}

const mapStateToProps = createStructuredSelector({
  channels: selectChannels(),
});

const mapDispatchToProps = (dispatch) => ({
  changeRoute: (url) => dispatch(push(url)),
  fetchChannels: () => dispatch(fetchChannels()),
});

export default connect(mapStateToProps, mapDispatchToProps)(Sidebar);

ChannelPage

class ChannelPage extends React.Component {
  componentDidMount() {
    console.log('##Fetch history messages##');
    this.props.fetchMessages(this.props.channel);
  }

  render() {
    return (
      {this.props.channel.name}
    );
  }
}

const mapStateToProps = createStructuredSelector({
  channel: selectChannel(),
});

export default connect(mapStateToProps, {
  fetchMessages,
})(ChannelPage);

appReducer

function appReducer(state = initialState, action) {
  switch (action.type) {
    case RECEIVE_CHANNELS:
      console.log('received channels');
      return state;
    case FETCH_CHANNELS:
      console.log('fetching channels');
      return state;
    case FETCH_MESSAGES:
      console.log('fetching history messages---WTF');
      return state;
    default:
      return state;
  }
}

export default appReducer;

reducer received unexpected FETCH_MESSAGES action demo

redux-devtools can only received LOCATION_CHANGE action when go to other channel page redux-devtools

Which one is the right behavior?

1 Answer 1

1

There are two questions

What's the best practice for loading data based on params in react component?

You can use componentDidUpdate() to dispatch request based on router params to get data from API

reducer received unexpected FETCH_MESSAGES action when navigate from messages/1 to messages/2

It's an expected behavior, reducer will receive previous action when navigate from messages/1 to messages/2, and the componentDidMount already ran once so it will never be called

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.