我如何用 'recompose' 重写它?

How do I rewrite this with 'recompose'?

我有这个 class 组件,想用 recompose:

将它重写为无状态功能组件
export default class Popular extends Component {
    state = {
        value: 0,
        selected: "All",
        repos: null
    }

componentDidMount() {
    this.handleSelected(this.state.selected)
}

handleChange = (e, value) => {
    this.setState({ value })
}

handleSelected = lang => {
    this.setState({
        selected: lang,
        repos: null
    })
    fetchPopularRepos(lang).then(repos => {
        this.setState({
            selected: lang,
            repos
        })
    })
}

在重构之前,我正在努力将 onSelectLanguageonFetchRepos 合并到一个函数中,就像在我的代码中一样。我也不知道如何为我的 componentDidMount 函数重写它。

更新:

得到这个工作:

const enhance = compose(
  withStateHandlers(initialState, {
    onChangeLanguage,
    onSelectLanguage
  }),
  lifecycle({
    componentDidMount() {
      fetchPopularRepos(this.props.selected).then(repos => {
        this.setState({
          repos
        })
      })
    }
  }),
  lifecycle({
    componentDidUpdate(prevProps) {
      if (this.props.selected !== prevProps.selected) {
        this.setState({ repos: null })
        fetchPopularRepos(this.props.selected).then(repos => {
          this.setState({
            repos
          })
        })
      }
    }
  })
)

虽然这些生命周期看起来不是很性感。不确定这是否值得重构。

这看起来像是您想要使用 the lifecycle() method 的情况。我不是 recompose 专家,但我认为以下调整可能会实现您所追求的目标:

const onFetchPopularRepos = props => () => {
    // Make sure the method returns the promise
    return fetchPopularRepos(props.selected).then(repos => ({  
        repos: repos
    }))
}

const withPopularReposState = withStateHandlers(initialState, {
    onChangeLanguage,
    onSelectLanguage
})

// Add a life cycle hook to fetch data on mount
const withLifecycle = lifecycle({
  componentDidMount() {

    // Update the state
    onFetchPopularRepos(this.props).then(newState => this.setState(newState)) 
  }
})();

// Compose the functional component with both lifecycle HOC
const enhance = withLifecycle(withPopularReposState)

扩展上一个答案,您可以根据需要使用功能组合来组合 onFetchReposonSelectLanguage。 如果我正确理解您的要求,您应该可以通过以下方式实现:

const initialState = {
    value: 0,
    selected: "All",
    repos: null
}

const onChangeLanguage = props => (event, value) => ({
    value
})

const onSelectLanguage = props => lang => ({
    selected: lang
})

const onFetchRepos = props => (fetchPopularRepos(props.selected).then(repos => ({
    repos
})))

// Combined function: onFetchRepos followed by call to onSelectLanguage
const onFetchReposWithSelectLanguage = props => onFetchRepos(props)
      .then(response => props.onSelectLanguage(response))

// Minimal code to compose a functional component with both state handers and 
// lifecycle handlers
const enhance = compose(
    withStateHandlers(initialState, {
        onChangeLanguage,
        onSelectLanguage
    }),
    lifecycle({
        componentDidMount() {
            // Fetch repos and select lang on mount
            onFetchReposWithSelectLanguage(this.props)
        }
    })
)

更新

// Minimal code to compose a functional component with both state handers and 
// lifecycle handlers
const enhance = compose(
    withStateHandlers(initialState, {
        onChangeLanguage,
        onSelectLanguage,
        setRepos
    }),
    lifecycle({
        componentDidMount() {
            // Reuse onSelectLanguage logic and call setState manually, use setState callback that
            // fires after state is updated to trigger fetch based on newState.selected language
            this.setState(onSelectLanguage(this.props.selected)(this.props), newState => {
                fetchPopularRepos(newState.selected).then(repos => {
                    this.setState({
                        repos
                    })
                })
            })
        }
    })
)

希望对您有所帮助!