【问题标题】:React / Next.js Change image src onLoadReact / Next.js 更改图像 src onLoad
【发布时间】:2020-12-22 21:15:06
【问题描述】:

在 React 中加载图像源之前添加 loader 的正确方法是什么?

这个带有 onLoad 函数的例子不能正常工作。我尝试了该状态,但它也不能很好地工作,因为加载第一张图像后状态会发生变化,因此它不适用于所有图像。

有什么帮助吗?

{posts.map( post => (
    <Card key={post.id}  id={post.id}>
      <Link href={ `/blog/${ post.slug }` }>

       <Image src={'/loading.gif'} onLoad(e => e.target.src={post.featured_image.post-crop}) unsized />

       <p>{post.title}</p>
     </Link>
    </Card>
))}

【问题讨论】:

    标签: reactjs next.js


    【解决方案1】:

    我认为您应该将图像的来源存储在状态中。

    例子

    const { useState, useEffect } = React;
    
    const loadingUrl = "https://media3.giphy.com/media/3oEjI6SIIHBdRxXI40/giphy.gif"
    
    const imageUrl = "https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg"
    
    const Image = ({src: _src}) => {
      const [src, setSrc] = useState(loadingUrl)
    
      const onLoad = () => {
        if(src === loadingUrl) {
          const timeout = 1000 + Math.floor(Math.random() * 2000)
        
          setTimeout(() => {
            setSrc(_src);
          }, timeout);
        }
      }
    
      return <img width="100" src={src} onLoad={onLoad}/>
    }
    
    const data = Array(3).fill(0).map(pr => ({imageSrc: imageUrl}))
    
    const App = () => {
      const [posts, setPosts] = useState(data);
    
      return <div>
        {posts.map((post, index) => <Image key={index} src={post.imageSrc}/>)}
      </div>
    }
    
    ReactDOM.render(
        <App />,
        document.getElementById('root')
      );
    <script src="https://unpkg.com/react/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <div id="root"></div>

    【讨论】:

    • 嗯,好的,但这是一张图片的好例子。我有帖子列表,每个帖子都有自己的图片需要加载。
    • 更新了例子,思路还是一样的,图片的来源必须保存在状态
    【解决方案2】:

    为此,最好创建自己的自定义可加载图像组件。该组件将包含一个 base64 编码的图像,作为加载微调器的 src 可用(因此不必加载太多......请参阅底部的代码框)并将处理整个加载图像。您还可以在单​​个组件中显示错误图像,或处理重试等。

    类似这样的东西(这是标准的反应,但你可以使用这个概念)

    const LoadableImage = (props) => {
      const [loaded, setLoaded] = useState(false);
    
      //you can always store errors to show an error image if it could not be found etc
      const [error, setError] = useState(null);
    
      const loadingImgStyle = {
        display: loaded ? "none" : undefined
      };
    
      const displayImgStyle = {
        display: loaded ? undefined : "none"
      };
    
      return (
        <div width={props.width} height={props.height}>
          <img src={Spinner} style={loadingImgStyle} alt={"Loading"} />
          <img
            src={props.src}
            width={props.width}
            height={props.height}
            alt="loadable"
            style={displayImgStyle}
            onLoad={() => setLoaded(true)}
          />
        </div>
      );
    };
    
    export default LoadableImage;
    

    现在您可以映射您的图像,并且每个图像都将控制自己的状态

    {posts.map( post => (
        <Card key={post.id}  id={post.id}>
          <Link href={ `/blog/${ post.slug }` }>
           <LoadableImage src={post.featured_image.post-crop}/>
           <p>{post.title}</p>
         </Link>
        </Card>
    ))}
    

    Codesandbox

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-28
      • 2019-03-15
      • 1970-01-01
      • 2020-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多