#14 React.js 加载、刷新数据 - 高阶组件


  • 0

    const loadAndRefresh = (url) => {
      return (WrappedComponent) => {
        class WrapperComponent extends React.Component{
          constructor(props){
            super(props)
            this.state = {
              //isLoading: false,
              content: ''
            }
          }
          componentWillMount(){
            this.handleRefresh()
          }
          handleRefresh(){
            this.setState({
              //isLoading: true,
              content: '数据加载中...'
            })
            getData(url).then((result)=>{
              this.setState({
                //isLoading: false,
                content: result
              })
            })
          }
          render(){
            return (
              <div>
                <WrappedComponent 
                  content={this.state.content} 
                  refresh={()=>{this.handleRefresh()}} 
                  {...this.props} 
                />
              </div>
            )
          }
        }
        return WrapperComponent
      }
    }
    

  • 0

    // getData(url) 已经可以直接使用
    // 本站的环境都可以使用 async/await
    const loadAndRefresh = (url) => {
      return (WrappedComponent) => {
        class NewComponent extends Component {
          constructor() {
            super();
            this.state = {
              content: ''
            }
          }
          async getData() {
            return await getData(url)
          }
          loadData() {
            this.setState({content: '数据加载中...'});
            this.getData().then((content)=>{
              this.setState({content})
            });
          }
          componentWillMount() {
            this.loadData();
          }
          handleFresh() {
            this.loadData();
          }
          render() {
            return <WrappedComponent
                content={this.state.content}
                refresh={this.handleFresh.bind(this)}
                {...this.props}
              />
          }
        }
        return NewComponent
      }
    }
    

  • 0

    // getData(url) 已经可以直接使用
    // 本站的环境都可以使用 async/await

    const loadAndRefresh = (url) => {
    return (UnWrappedComponent) => {
    class WrappedComponent extends Component {
    constructor (props) {
    super(props)
    this.state = {
    content: '数据加载中...'
    }
    }

            componentWillMount () {
                this.refresh()
            }
    
            refresh = () => {
                this.setState( { content: '数据加载中...'} )
                var getUrl = getData(url)
                getUrl.then((res) => {
                    this.setState({content: res})
                })
            }
    
            render() {
                return(
                    <UnWrappedComponent 
                        refresh={ this.refresh.bind(this) }
                        content={ this.state.content}
                        {...this.props}
                    />
                )
            }
        }
        return WrappedComponent
    }
    

    }


  • 0

    ...this.props
    一直不是很理解这个语句,为什么还要传递整个props呢,content和refresh不是已经传进去了么


  • 0

    @zhongshankaka 因为他还有可能有其他的props,就是父组件传给他的,这里面只是继承后,再给他添加两个props而已,应该是是这样的


  • 0

    @ScriptOJ 您好,我想请问下render函数里面的...this.props中的this为什么是指向WrappedComponent的?这行代码的this和其他地方的this指向不一样的?


  • 0

    @ScriptOJ 为什么这里没有初始化state就直接用setstate呀?这样的写法规范么?谢谢~


  • 0

    // getData(url) 已经可以直接使用
    // 本站的环境都可以使用 async/await
    
    const loadAndRefresh = (url)=>(WrappedComponent)=>{
      class NewComponent extends Component{
        constructor(){
          super();
          this.state = {
            content:null
          }
        }
        componentWillMount(){
           this.setState({content:"数据加载中..."})
          // const content = await getData(url)
          getData(url).then((content)=>{
            this.setState({content})
          });
        }
        handleRefresh(){
          this.componentWillMount();
        }
        render(){
    
          return(
            <WrappedComponent  content ={this.state.content}  refresh={ this.handleRefresh.bind(this)} {...this.props}/>
            )
        }
      }
      return NewComponent
     
    }
    

  • 0

    const loadAndRefresh = url => Component =>
      class WrappedComponent extends React.Component {
        state = {
          content: ''
        }
      
        refresh = async () => {
          this.setState({
            content: '数据加载中...'
          })
          
          const content = await getData(url)
          
          this.setState({
            content
          })
        }
      
        render () {
          return <Component {...this.props} content={ this.state.content } refresh={ this.refresh } />
        }
        
        componentWillMount () {
          this.refresh()
        }
      }
    
    

  • 0

    const loadAndRefresh = url => WrappedComponent => {
    class NewComponent extends React.Component {
    constructor () {
    super()
    this.state = {
    content: ''
    }
    }

    componentWillMount () {
      this.refresh()
    }
    
    async refresh () {
      let content = ''
      this.setState({
        content: '数据加载中...'
      })
      content = await getData(url)
      this.setState({
        content
      })
    }
    
    render () {
      return (
        <WrappedComponent
          {...this.props}
          content={this.state.content}
          refresh={this.refresh.bind(this)}
        />
      )
    }
    

    }
    return NewComponent
    }


  • 0

    @ScriptOJ “所有传给 loadAndRefresh 返回的组件的 props 要原封不动传给被包裹的组件”这句话很难理解


  • 0

    @chwech 这句话确实很难理解,不过看了讨论区贴出的代码就懂了


  • 0

    形参组件名要大写 被坑的无言以对


  • 0

    贴一下我写的烂代码...

    const loadAndRefresh = (url) => (WrappedComponent) => {
    
      class HigherComponent extends Component {
        
        constructor() {
          super()
          this.state = {
            content: '数据加载中...'
          }
        }
      
        componentDidMount() {
          this.handleRefresh()
        }
        
        handleRefresh() {
          this.setState({content: '数据加载中...'})
          getData(url).then((data) => this.setState({content: data}))
        }
        
        render() {
          return (
            <WrappedComponent content={this.state.content} refresh={this.handleRefresh.bind(this)}  {...this.props} />
          )
        }
      }
      
      return HigherComponent
      
    }
    

  • 0

    @shippom#14 React.js 加载、刷新数据 - 高阶组件 中说:
    报错“数据加载完成没有传入正确的 content 数据”,又没看出哪里错了

      return function(Component){
         return class lof extends Component{
          constructor(){
            super();
            this.state = {dcontent:''};
          }
          componentWillMount(){
            this.refresh();
          }
          componentWillUpdate(){
            this.refresh();
          }
          refresh(){
            this.setState({dcontent:'数据加载中...'});
            var d = getData(url);
            d.then(v=>{
              this.setState({dcontent:d});
            })
          }
          render(){
            return (<Component content={this.state.dcontent} refresh={this.refresh.bind(this)} {...this.props}/>)
          }
        }
      }
    }
    

  • 0

    // getData(url) 已经可以直接使用
    // 本站的环境都可以使用 async/await
    
    const loadAndRefresh = (url)=>{
      return (WrappedComponent)=>{
        class AjaxAction extends Component{
          constructor(){
            super()
            this.state={
              content:'数据加载中...'
            }
          }
          componentWillMount(){
            this.handleGetData()
          }
          async handleGetData(){
            this.setState({
              content:'数据加载中...'
            })
            const content=await getData(url)
            this.setState({
              content
            })
            return content
          }
          render(){
            return (
                <WrappedComponent content={this.state.content} refresh={this.handleGetData.bind(this)} {...this.props}/>
              )
          }
        }
        return AjaxAction
      }
    }
    
    

  • 0

    @chwech 高阶组件的原则,就是给原有的组件新增一些功能,但不能干扰到原有组件自带的属性、行为。所以高阶组件render时,需要使用{...this.props},这样子将props原封不动传到原有组件中。


  • 0

    const loadAndRefresh = url => Component => {
      class NewComponent extends React.Component {
        constructor() {
          super();
          this.state = {
            content: '数据加载中...'
          };
        }
        
        componentWillMount() {
          this.handleRefresh();
        }
        
        async handleRefresh() {
          this.setState({
            content: '数据加载中...'
          });
          const content = await getData(url);
          this.setState({
            content
          });
        }
        
        render() {
          return (
            <Component content={this.state.content}
              refresh={this.handleRefresh.bind(this)}
              {...this.props}
            />
          );
        }
      }
      
      return NewComponent;
    }

  • 0

    @anrgct

     refresh(){
            this.setState({dcontent:'数据加载中...'});
            var d = getData(url);
            d.then(v=>{
              this.setState({dcontent:d}); // 应该是 v
            })
          }
    

  • 0

    @orange
    嗯嗯,发现蛮多问题,谢谢指出
    /*
    这段加上也出错了,删掉
    componentWillUpdate(){
    this.refresh();
    }
    */


登录后回复
 

与 ScriptOJ 的连接断开,我们正在尝试重连,请耐心等待