简体   繁体   中英

ReactJS Functional Component Renders Multiple Times and Setting Img Src With Props

I am a newbie in ReactJS and I am trying to pass an object as a props to a component. I am getting data from the .NET CORE WEB API and there is no problem about it. Here is my useEffect hook to do that:

 useEffect(() => { const response = axios.get("http://localhost:5122/GetUserInfo", { params: { userId: profileId } }); response.then((res) => { setUserInfo(res.data); }) }, [])

And I pass the userInfo state as props, as shown below:

 return ( <div> <ProfileCard user={userInfo} /> </div> );

To better understand of problem I took a screenshot of console. I am print user prop at the top of ProfileCard component. Console Screenshot

My problem is: When I try to use props such as <label>{user.profilePicture}</label> I can see the file name on the screen but when I try to use props such as <img src={require(./File/${user.profilePicture})} /> cannot see the image on the screen and throws an error to console that basically saying cannot find the image. Note: I am sure that given source path is correct and image file exist.

Anybody help me please? Edit: I also added the console error. 在此处输入图像描述

Your screenshot shows that profilePicture is a filename à la 36ddd13a-d3b9-47ad-9719-7789892a1384.jpg .

  • Just doing <img src={profilePicture} /> would have your browser attempt to find the file by relative path, which is likely not to work.
  • require(...) only works for assets that are available at the build time of your React app and only for static strings due to bundling; an arbitrary filename that comes over the wire from your API won't be that.
  • If your HTTP server serves those images from under /File , then you'd need to do
    <img src={`/File/${profilePicture}`} />
    (or, if that HTTP server is not the same origin your React app is served from, but that http://localhost:5122/ from above),
     <img src={`http://localhost:5122/File/${profilePicture}`} />
    ).
    • If you're using eg create-react-app, then you'd need to put the file in the /public/File/ directory.

You can't pass dynamic strings to require like require(./File/${user.profilePicture})

It maybe work sometimes, but only in some edge cases.

What you should do is tell the compiler exactly which files it needs to bundle:

const map = {
  'profilePic_1': require('./File/profilePic_1'),
  'profilePic_2': require('./File/profilePic_2'),
  // and so on...
}

By creating a map you can then "index" the bundled files based on server response.

<img src={map[user.profilePicture]} />

If you have a fairly large number of images I'd recommend dynamically loading them:

const map = {
  'profilePic_1': () => import('./File/profilePic_1'),
  'profilePic_2': () => import('./File/profilePic_2'),
  // and so on...
}

const YourComponent = ({userProfilePicture})
{
  // without placeholder
  const [url, setUrl] = useState('');

  // if you want to load a placeholder from a server
  // const [url, setUrl] = useState('http://placeholder_url');

  // if you want to bundle the placeholder
  // const [url, setUrl] = useState(require('./placeholder_url'));

  useEffect(() => {
    map[userProfilePicture]().then(setUrl);
  }, []);

  return <img src={url} alt=''/>;
}

Please can you post the entire component with the useEffect and also the ProfileCard component.

It might be a problem with the useState. You should have something like

const [userInfo, setUserInfo] = useState<TypeOfGetUserInfo | null>(null)

In you ProfileCard you should have something like

const ProfileCard = React.FC<ProfileCardProps> = ({user}) => {


...

  return (
   ...something
  )
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM