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


  • 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();
    }
    */


  • 0

    const loadAndRefresh = url => WrapperComponent => {
      return class NewComponent extends Component {
        constructor() {
          super()
          this.state = {
            content: "数据加载中...",
          }
        }
    
        componentWillMount() {
          this._getData(url)
        }
    
        _getData(url) {
          this.setState({
            content: "数据加载中...",
          })
          getData(url).then(content => {
            this.setState({ content })
          })
        }
    
        handleRefreshAction() {
          this._getData(url)
        }
    
        render() {
          return (
            <div>
              <WrapperComponent
                content={this.state.content}
                refresh={this.handleRefreshAction.bind(this)}
                {...this.props}
              />
            </div>
          )
        }
      }
    }
    
    

  • 0

    @ScriptOJ
    参考答案里面是不是忘记写

    state = {
         content: '数据加载中...'
     }
    


  • 0

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

  • 0

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

  • 0

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

      componentDidMount(){
        this.refresh();
      }
      
      refresh(){
        this.setState({
            content: '数据加载中...'
          })
        getData(url).then((data)=>{
          this.setState({
            content: data
          })
        })
      }
      
      render () {
        return (
          <Post
            content={this.state.content}
            refresh={this.refresh.bind(this)}
            {...this.props} />
        )
      }
    }
    return LoadAndRefreshActions
    

    }


  • 0

    @ScriptOJ 代码写得漂亮,学到了~


  • 0

    这道题同时考察了高阶函数和高阶组件,棒!


  • 0

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

  • 0

    为什么我用本地用
    Post = loadAndRefresh('/post')(Post)
    会报错提示:“无法分配到“Post”,因为它不是变量。ts(2539)”
    希望大佬解释下,,是不是不能重新赋值class


登录后回复
 

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