useState для обновления свойства объекта - PullRequest
2 голосов
/ 04 апреля 2020

Я новичок в React. У меня есть функциональный компонент, который используется для рендеринга изображения и некоторых свойств изображения, передаваемого как компонент в компонент. Я хотел бы обновить источник изображения при ошибке рендеринга изображения. Я также хотел бы обновить свойство состояния родительского компонента и передать его родителю. Я не уверен, как добиться того же. Я так долго боролся за это. Пожалуйста, кто-нибудь может помочь мне решить эту проблему. Большое спасибо заранее.

Родительский компонент:

import React, {
  useState
} from 'react';
import PropTypes from 'prop-types';
import ImageRenderer from './ImageRenderer';
import VideoRenderer from './VideoRenderer';

const getComponent = {
  'image': ImageRenderer,
  'video': VideoRenderer
}

const AssetRenderer = (props) => {
    console.log('props in asset ren:', props);
    const [assetInfo, setAssetInfo] = useState(props);
    console.log('assetInfo in parent:', assetInfo);
    const isPublished = assetInfo.assetInfo.isAssetPublished;
    let source = assetInfo.assetInfo.assetUrl;
    const PreviewComponent = getComponent[assetInfo.assetInfo.type];
    return ( < div > {
        isPublished && source && < PreviewComponent assetInfo = {assetInfo} setAssetInfo = { setAssetInfo } />} </div>
      );
    }

    AssetRenderer.propTypes = {
      assetInfo: PropTypes.object.isRequired
    };
    export default AssetRenderer;

Дочерний компонент:

import React from 'react';
import PropTypes from 'prop-types';
import {
  Subheading
} from '@contentful/forma-36-react-components';

const ImageRenderer = props => {
  console.log('inside image renderer', props);
  return ( <
    div id = "asset-img" >
    <
    Subheading > Image preview: < /Subheading> <
    p > Name: {
      props.assetInfo.assetInfo.name
    } < /p> <
    p > Type: {
      props.assetInfo.assetInfo.type
    } < /p>  <
    p > Url: {
      props.assetInfo.assetUrl
    } < /p>  <
    img src = {
      props.assetInfo.assetInfo.assetUrl
    }
    alt = "name"
    onError = {
      e => {
        props.setAssetInfo(assetInfo => {
          return { ...props.assetInfo.assetInfo,
            assetUrl: 'https://example.com/404-placeholder.jpg',
            isAssetPublished: false
          } //would like to update the asset url to 404 and also set isAssetPublished to false and pass it back to parent to update parent state 
        });
      }
    }
    /> <
    /div> 
  )
}
ImageRenderer.propTypes = {
  assetInfo: PropTypes.object.isRequired
};
export default ImageRenderer;

Ответы [ 2 ]

3 голосов
/ 04 апреля 2020

Вместо использования нового состояния в компоненте ImageRenderer, вы можете просто передать setState of Parent с помощью таких реквизитов, как этот;

родительский компонент

import React, { useStae } from 'react'

const parentCompoennt = props => {
  const [assetInfo,setAssetInfo] = useState();
  return (
    <ImageRenderer assetInfo={assetInfo} setAssetInfo={setAssetInfo} />
  );
}

компонент imageRenderer

const ImageRenderer =  props =>  {


    return(
        <div id="asset-img">
             <p> Name: {props.assetInfo.assetInfo.name} </p>
             <p> Type: {props.assetInfo.assetInfo.type} </p> 
             <p> Url: {props.assetInfo.assetInfo.assetUrl} </p> 
            <img src={props.assetInfo.assetInfo.assetUrl}  alt="name"  onError={e => {
                    props.setAssetInfo(assetInfo => {
                        return { ...props.assetInfo, assetUrl: 'https://example.com/404-placeholder.jpg' } //would like to update the asset url to 404 and also set isAssetPublished to false and pass it back to parent to update parent state 
                    });
            }}/>
        </div> 
    )
}

1 голос
/ 04 апреля 2020

Если цель состоит только в том, чтобы обрабатывать только ошибки изображения, то вы можете добиться этого без повторного рендеринга компонента:

<img src={assetInfo.assetInfo.assetUrl} alt="name"
     onError={e => {
          e.target.src = 'https://example.com/404-placeholder.jpg';
     }}
/>
...