使用recompose()进行异步的示例?

时间:2017-08-16 16:31:15

标签: reactjs recompose

我有以下代码完全有效,但它的一部分(_FetchJSON)是重构之外的自定义HOC

(现场演示@ https://codepen.io/dakom/pen/zdpPWV?editors=0010

const LoadingView = () => <div>Please wait...</div>;
const ReadyView =  ({ image }) => <div> Got it! <img src={image} /> </div>;                        

const Page = compose(
    _FetchJson, 
    branch( ({ jsonData }) => !jsonData, renderComponent(LoadingView)),
    mapProps(
      ({jsonData, keyName}) => ({ image: jsonData[keyName] }) 
    )
)(ReadyView);

const ThisPage = <Page request={new Request("//api.github.com/emojis")} keyName="smile" />

//That's it!

ReactDOM.render(ThisPage, document.getElementById("app"));


/* 
 * Imaginary third party HOC
 */

interface FetchJsonProps {
    request: Request;
}
function _FetchJson(WrappedComponent) {
    return class extends React.Component<FetchJsonProps> {
        componentDidMount() {
            fetch(this.props.request)
                .then(response => response.json())
                .then(this.setState.bind(this));
        }

        render() {
            return <WrappedComponent jsonData={this.state} {...this.props} />
        }
    }
}

如何更改_FetchJson以便在重构中工作?最有帮助的(不仅仅是我 - 但仅供参考)将是两个解决方案:

  1. 使用lifecycle()
  2. 使用mapPropsStream()
  3. 注意:我确实尝试过生命周期()方式但是没有用:

    const _FetchJson = compose(
        withStateHandlers(undefined,
            {
                onData: state => ({
                    jsonData: state
                })
            }),
            lifecycle({
                componentDidMount() {
                    fetch(this.props.request)
                    .then(response => response.json())
                    .then(this.props.onData.bind(this));
                }
            })
        );
    

1 个答案:

答案 0 :(得分:5)

你去了:

const fetchJson = compose(
  withStateHandlers(null, {
    onData: state => data => ({
      jsonData: data
    })
  }),
  lifecycle({
    componentDidMount() {
      fetch(this.props.request)
        .then(response => response.json())
        .then(data => this.props.onData(data));
    }
  })
);