代码之家  ›  专栏  ›  技术社区  ›  karolis2017

如何用“重新组合”重写这个?

  •  1
  • karolis2017  · 技术社区  · 8 年前

    我有这个类组件,并想重写它为无状态功能组件与 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
            })
        })
    }
    

    我在努力组合 onSelectLanguage 和 onFetchRepos 在一个函数中,比如在重构之前的代码中。我也不知道如何为我的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
              })
            })
          }
        }
      })
    )
    

    2 回复  |  直到 8 年前
        1
  •  0
  •   Dacre Denny    8 年前

    在前面答案的基础上,您可以使用函数组合来组合 onFetchRepos 和 onSelectLanguage 如果我正确理解您的要求,您应该能够通过以下方式实现这一点:

    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
                        })
                    })
                })
            }
        })
    )
    

    希望这对你有帮助!

        2
  •  1
  •   Dacre Denny    8 年前

    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)