react 使用 render prop component 请求数据

在 React 中,高阶组件的替代方式是 render prop 组件。也可以使用 render prop 组件来进行声明式的数据获取。

class Fetcher extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      data: null,
      isLoading: false,
      error: null,
    };
  }

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

    axios.get(this.props.url)
      .then(result => this.setState({
        data: result.data,
        isLoading: false
      }))
      .catch(error => this.setState({
        error,
        isLoading: false
      }));
  }

  render() {
    return this.props.children(this.state);
  }
}

然后,你可以在你的 App 组件中按照以下方式使用 render prop 组件:

const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';

...

const RenderPropApproach = () =>
  <Fetcher url={API + DEFAULT_QUERY}>
    {({ data, isLoading, error }) => {
      if (!data) {
        return <p>No data yet ...</p>;
      }

      if (error) {
        return <p>{error.message}</p>;
      }

      if (isLoading) {
        return <p>Loading ...</p>;
      }

      return (
        <ul>
          {data.hits.map(hit =>
            <li key={hit.objectID}>
              <a href={hit.url}>{hit.title}</a>
            </li>
          )}
        </ul>
      );
    }}
  </Fetcher>

通过使用 React 的 children 属性作为 render prop,你可以传递 Fetcher 组件中的所有本地状态。这样,你就可以在 render prop 组件中进行所有的条件渲染和最终渲染。