首页 > 解决方案 > React,如何将值从函数返回到组件?

问题描述

我想在我的组件中做一个基本操作,因为我需要在检查图像是否正确加载后if, else返回一个[boolean] 。

export const Suggest = (props) => {
  function handleLoad(url) {
    let image = new Image();
    image.src = url;

    image.onload = function() {    
      return false;
    }

    image.onerror = function() {    
      return true;
    }
  }

  return (
    <div>
      { 
        props.state.suggestions.map((item, i) => 
          <div key={i}>
            <span>Boolean {i} = {handleLoad(item.image) ? 'True' : 'False'}</span>
          </div>
        )
      }
    </div>
  )
}

不幸的是调用函数handleLoad(item.image)返回null

我应该如何解决这个问题?

标签: javascriptreactjs

解决方案


handleLoad函数不返回任何内容,undefined默认情况下会返回。onloadonerror被分配了新的功能。

由于您正在加载图像(异步操作),因此无法同步返回结果。您将需要使用承诺,例如

function handleLoad(url) {
  return new Promise(function (resolve, reject) {
    let image = new Image();
    image.src = url;

    image.onload = function() { 
        resolve();
    }

    image.onerror = function() {    
        reject(new Error('Image loading failed'));
    } 
  });
}

然后,您可以在 上加载您的图像componentDidMount,并使用then回调来相应地设置您的状态:

// This is just a helper method to set the loaded
// flag and update the state for a given suggestion.
// Added it to avoid repeating ourselves.
setSuggestionLoaded = (suggestionIndex, isLoaded) => {
    let suggestions = this.state.suggestions;
    suggestions[suggestionIndex].loaded = isLoaded;
    this.setState({ suggestions: suggestions });
}

componentDidMount() {
    this.state.suggestions.map((suggestion, i) => {
        handleLoad(suggestion)
        .then(() => {
            setSuggestionLoaded(i, true);
        })
        .catch((err) => {
            setSuggestionLoaded(i, false);
        }));
    })
}

然后你可以渲染你的状态,它会在加载操作完成或失败时更新。

  return (
    <div>
      { 
        props.state.suggestions.map((item, i) => 
          <div key={i}>
            <span>Boolean {i} = {item.loaded ? 'True' : 'False'}</span>
          </div>
        )
      }
    </div>
  )

另一种选择是通过普通的旧回调,例如:

function handleLoad(url, successCallback, errorCallback) {
    let image = new Image();
    image.src = url;

    image.onload = function() { 
        if(successCallback) successCallback();
    }

    image.onerror = function() {
        if(errorCallback) errorCallback(new Error('Image loading failed'));
    } 
}


componentDidMount() {
    this.state.suggestions.map((suggestion, i) => {
        handleLoad(suggestion,
            () => {                
                setSuggestionLoaded(i, true);
            },
            (err) => {
                setSuggestionLoaded(i, false);
            }
        );
    })
}

但我个人建议使用 promises 方法。我会更进一步,建议您阅读新async / await语法,它本质上是编写基于 Promise 的异步 JavaScript 的一种很好的方式。


推荐阅读