programing

이미지 파일을 다시 로드하도록 강제 리액트하시겠습니까?

mbctv 2023. 3. 17. 21:56
반응형

이미지 파일을 다시 로드하도록 강제 리액트하시겠습니까?

마이 리액트 앱에서는 프로필 이미지를 업로드 할 수 있습니다.이 작업은 이미지를 Amazon S3 버킷에 업로드하고 이미지에 대한 경로와 이미지를 업로드한 날짜 및 시간을 데이터베이스에 저장함으로써 수행됩니다.이미지의 파일명은, 유저의 ID 로 설정됩니다.

사용자가 새로운 이미지를 업로드 할 때 문제가 발생합니다.이미지 경로가 같기 때문에 React는 아무것도 변경되지 않았습니다.즉, 변경 내용을 확인하려면 페이지를 새로 고쳐야 합니다.

날짜 필드가 있기 때문에 componentWillReceiveProps를 사용하여 새로운 이미지가 업로드된 시기를 알 수 있습니다.다음 console.log는 올바른 시간에 실행됩니다.

componentWillReceiveProps(nextProps) {
    if (this.state.picDate.getTime() !== nextProps.user.pic.date.getTime()) {
        console.log('image date has changed');
        // this.forceUpdate();
    }
}

이걸로 이미지를 다시 렌더링할 수 있나요?나는 노력했다.this.forceUpdate()효과가 없어요.

브라우저 캐시 때문인 것 같아요.같은 해시를 추가해 보다date.now()이미지 URL 변경 후.예를 들어 다음과 같습니다.

setState({
   imageSrc: '...',
   imageHash: Date.now()
})

및 렌더링:

render(){
  return(
      <img src={`${imageSrc}?${imageHash}`} />
  )
}

로컬 이미지에 문제가 있었습니다.이미지는 수정 중이었지만 URL은 그대로였습니다.

요령은 이미지가 변경될 때마다 변경되는 이미지에 키 속성을 추가하는 것이었습니다.예:

<Image key={Date.now()} source={{uri: <your local uri>}/>

출처: 이 GitHub 코멘트

난 괜찮아.

<img src={`${props.src}?${new Date().getTime()}`} />

이미지가 표시되지 않도록 처음에 상태를 null로 설정하고 경로를 사용하여 상태를 다시 특정 이미지로 설정할 수 있습니다.

constructor(props){
    super(props);
    this.state = {
         image_path : 'before update image path'
    };
}    

componentWillReceiveProps(nextProps) {
    if (this.state.picDate.getTime() !== nextProps.user.pic.date.getTime()) {
        console.log('image date has changed');
        //now here set state
        this.setState({
          image_path : 'your new image path or older as you explained both are same' + '?' + Math.random()
        });
    }
}

(Eric Wiener 답변 확장), s3에 업로드할 때 키(타임스탬프)를 설정하여 보다 깔끔한 갱신을 얻을 수 있습니다.

const [timestamp, setTimestamp] = React.useState(Date.now());

axios.post("/api/upload/s3", formData)
    .then(res => {
        setTimestamp(Date.now())
    })

<Avatar key={timestamp} className={classes.avatar} src={user_info.avatar} onClick={handleOpenPicture}></Avatar>

더 나은 해결책은 코드와 API의 구조를 변경하는 것일 수 있습니다.

해결 방법 1 개체에 updated Date를 추가하여 사용합니다.완전한 날짜 값이어야 합니다.

const bypassCache = new Date(updatedDate).getTime()
const imageUrl = `${image.url}?${bypassCache}`

// imageUrl = https://example.com/userId/imageId?16504372055

이전 항목과 비교하여 새 항목에 고유한 값이 필요합니다.비교가 필요한 경우 useRef를 사용하여 초기값을 유지한 후 새로운 updatedDate와 비교할 수 있습니다.

솔루션 2 경로 이름 자체에 bypassCache를 저장합니다.https://example.com/userId/imageId/bypassCache

따라서 "백엔드"에서 처리합니다.사용자의 프라이버시에는 실제 타임스탬프로 해석/반환할 수 없는 다른 고유값을 사용할 수 있습니다.

이미지 경로를 공백으로 설정한 다음 경로가 무엇이든 간에 설정하면, 리액션이 변경되었다고 가정하고 새 사진이 로드됩니다.

this.setState({image_path : ''});               
this.setState({image_path : 'Actual Image Source'});

my my my my my myFileUpload

this.setState({userimage:''});  
this.setState({userimage:"http://localhost:5000/auth/getProfilePic/" + this.state.username,});

이 솔루션은 다음과 같이 bypassCache를 추가하는 것입니다.

image.src = url + "?" + Math.random().toString(36); 

이미지 URL에 쿼리 매개 변수로 현재 날짜 추가

<img src={`${image_url}?${global.Date.now()}`} />

기능 컴포넌트에서는 동작합니다(클래스 베이스의 컴포넌트에서는 동작하지 않습니다).

const MyComponent = () => {
  const [source, setSource] = useState('some_image.png');

  const changeImage = (newSource) => {
    setSource(null);
    setTimeout(() => setSource(newSource));
  };

  return (
    <img 
      src={source}
    />
  );
};

메모: 랜덤 해시를 사용해 보고 키를 변경해도 동작하지 않습니다. 이 방법이 효과적일 수 있습니다.

새로운 업로드를 할 때마다 이미지 이름을 변경하는 것이 효과가 있었습니다.예를 들어 다음과 같습니다.

const new_file_name = Date.now() . '/' . file_extension

이 새 파일 이름은 사용자와 관련된 일부 데이터베이스에 저장해야 합니다.또, 2명의 유저가 같은 이미지명을 가지지 않게 하기 위해서, 각 유저에 폴더를 가지는 것도 좋은 방법입니다.

앱 로드 시 api에서 사용자 이미지명을 요청하시면 파일명이 나옵니다.사용자를 알고 있기 때문에 어떤 폴더에서 검색해야 하는지 알고 있습니다.

파일을 업로드 할 때 이미지 변경을 즉시 확인하려면 이 파일 이름을 react 또는 redux 상태로 저장하십시오.Image 요소는 변경 시 다시 렌더링됩니다.

API에서 이미지를 가져오려면 다음과 같이 하십시오.

<Image
  source={{ 
    uri: your_localhost_ip + ':' + your_port +'/'+ your_folder_containing_all_user_pics + '/' + user_id + '/' + user_picture,
    cache:'reload' //only works for ios
  }}
/>

언급URL : https://stackoverflow.com/questions/47922687/force-react-to-reload-an-image-file

반응형