反应,如何从函数返回值到组件?

时间:2019-06-06 08:00:42

标签: javascript reactjs

我想在组件内部执行基本的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

我应该如何解决此问题?

1 个答案:

答案 0 :(得分:1)

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

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

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的漂亮方法。