反应取决于路由器参数的获取数据HoC

时间:2018-04-10 00:36:39

标签: javascript reactjs react-router

我有一个HoC,可以获取数据并返回加载屏幕或注入数据的底层组件。

现在的问题是被提取的数据取决于a)当前URL和b)URL参数。我使用的是React Router v4。所以我所做的基本上是在该组件中放了很多switch个案例。哪个有效并且做了我想做的事情,但我宁愿没有这个HoC中的切换案例。

const fetchesData = (WrappedComponent) => {
  class FetchesData extends React.Component {
    constructor(props) {
      super(props);
      this.fetchData = this.fetchData.bind(this);
      this.state = {isLoading: true};
    }

    fetchData() {
      this.setState({isLoading: true});

      const {match, dispatch} = this.props;
      const {params} = match;

      let action = () => {};
      switch (match.path) {
      case '/': {
        action = () => dispatch(
          fetchPopularArticles()
        );
        break;
      }
      case '/artists/:slug': {
        action = () => dispatch(
          fetchArtistWithArticles(params.slug)
        );
        break;
      }
      // ... more
      }

      action()
        .then((res) => {
          this.setState({
            ...this.state,
            isLoading: false,
          });
        });
    }

    componentDidMount() {
      this.fetchData();
    }

    render() {
      return (
        !!this.state.isLoading ?
          <LoadingComponent/> :
          <WrappedComponent
            {...this.props}
          />
      );
    }
  }
  return withRouter(connect()(FetchesData));
};

我更喜欢以某种方式从底层组件中注入fetchData()函数。或者也许来自父(路由器)组件。

第一个我不确定是否可能,因为它必须首先安装底层组件,这会带来比其他任何事情更多的麻烦。

前者我不知道我会怎么做,因为我需要知道路线的参数。

我的路线渲染看起来像这样:

[
  <Route
    exact={true}
    key={0}
    path={'/'}
    render={(props) => (
      <fetchesData(Home)
        {...props}/>
    )}/>,
  // ... more routes
]

对此有什么好的做法?

如果它有帮助,那么来源:

1 个答案:

答案 0 :(得分:1)

在反应数据向下流动时,首选方法是从fetchData组件传递Render方法。您可以将方法传递给fetchesData,就像这样

const FetchedHome = fetchesData(Home, fetchPopularArticles)
const FetchedArtists = fetchesData(Home, fetchArtistWithArticles) 
//   ....
<Route
exact={true}
key={0}
path={'/'}
render={(props) => (
  < FetchedHome {...props}/>
)}/>

然后在fetchesData内调用传递的方法

const fetchesData = (WrappedComponent, fetchMethod){
  //....
  componentDidMount() {
    const {match, dispatch} = this.props
    dispatch(fetchMethod(match.params));
  } 
}

将操作更改为接受对象

const fetchArtistWithArticles = ({slug: artistSlug})

如果您不想更改操作,可以将match.params中的映射对象传递给要发送的函数属性。