简体   繁体   中英

Changing image source property of a child with dangerously set innerhtml parent attribute in React

I have a Front end application which uses react and fetches data using API calls from the strapi backend. I have provided a rich text field to the user in strapi backend where the user can also upload an image along with data as shown Strapi Backend .
On the react side I am fetching data using API call with help of axios and displaying data as shown in the code

 const [data, setData] = useState({});
    useEffect(() => {
    callApi(the_get_data_url); // Calls the API and sets state using setData so now data field 
    //has all the data
     }, []);

This is a sample of what data variable will contain.

{
  "Subscription": "standard",
  "_id": "610bc1265aeb5e38e42c8220",
  "Headline": "How to stop screwing yourself over",
  "Description": "<p>How do you get on the road to being happier? Start by setting your alarm for 30 minutes earlier than usual and not hitting the snooze button. The effort required to leave that warm bed and enter the world is the same amount of effort needed to shake up your life and make that elusive change. In this humorous and provocative talk, Mel Robbins explains how turning off our brain's autopilot and demolishing our comfort zones is key to a rewarding life.</p><p><img src=\"/uploads/photo_1483985988355_763728e1935b_ixid_Mnwx_Mj_A3f_DB_8_M_Hxz_ZW_Fy_Y2h8_M_Xx8_Zm_Fza_Glvbnxlbnwwf_Hwwf_Hw_3_D_and_ixlib_rb_1_2_5186b4137a.1&amp;w=1000&amp;q=80\" alt=\"\"></p>",
  "published_at": "2021-08-05T13:06:47.325Z"
}

As you can see the Description field contains HTML tag as well as well as image tags.So what I am doing on the front end react to display this data is

<div id="description" dangerouslySetInnerHTML={{ __html: data?.Description }}></div>

Now the problem is that image is not coming because its source is not fully correct.

<img src="/uploads/photo_1483985988355_763728e1935b_ixid_Mnwx_Mj_A3f_DB_8_M_Hxz_ZW_Fy_Y2h8_M_Xx8_Zm_Fza_Glvbnxlbnwwf_Hwwf_Hw_3_D_and_ixlib_rb_1_2_5186b4137a.1&amp"/>

Its correct source is in development environment "http://localhost:1337/"+ source from strapi or for production environment process.env.React_BACKEND_URL + source from strapi I have included Jquery for changing source of the image by $("#description").find('img').attr('src') but I am not able to proceed further than this. Can anyone help me how to update the source property correctly. I have also tried the following function

import $ from "jquery";
window.onload = function () {
  setTimeout(CorrectURL, 3000);
};
function CorrectURL() {
  var images = [];

  images = $("#description p img").each(() => {
    var $img = $(this);
    console.log("The source is" + $img.attr("src")); // Getting undefined here
    return $img.attr("src");
  });

  window.images = images;
}

You should just forget jQuery, especially in a React.js component. You could simply use replaceAll here, like this:

 let data = { "Subscription": "standard", "_id": "610bc1265aeb5e38e42c8220", "Headline": "How to stop screwing yourself over", "Description": "<p>How do you get on the road to being happier? Start by setting your alarm for 30 minutes earlier than usual and not hitting the snooze button. The effort required to leave that warm bed and enter the world is the same amount of effort needed to shake up your life and make that elusive change. In this humorous and provocative talk, Mel Robbins explains how turning off our brain's autopilot and demolishing our comfort zones is key to a rewarding life.</p><p><img src=\"/uploads/photo_1483985988355_763728e1935b_ixid_Mnwx_Mj_A3f_DB_8_M_Hxz_ZW_Fy_Y2h8_M_Xx8_Zm_Fza_Glvbnxlbnwwf_Hwwf_Hw_3_D_and_ixlib_rb_1_2_5186b4137a.1&amp;w=1000&amp;q=80\" alt=\"\"></p><p>Yet another image for fun <img src=\"/uploads/photo_1483985988355_763728e1935b_ixid_Mnwx_Mj_A3f_DB_8_M_Hxz_ZW_Fy_Y2h8_M_Xx8_Zm_Fza_Glvbnxlbnwwf_Hwwf_Hw_3_D_and_ixlib_rb_1_2_5186b4137a.1&amp;w=1000&amp;q=80\" alt=\"\"></p>", "published_at": "2021-08-05T13:06:47.325Z" } function addHost(str, host) { return str.replaceAll('src=\"/uploads', `src=\"${host}/uploads`) } console.log(addHost(data.Description, 'https://images.example.com'))

Or split the Description at the uploads substring to an array and join them again by adding the host:

 let data = { "Subscription": "standard", "_id": "610bc1265aeb5e38e42c8220", "Headline": "How to stop screwing yourself over", "Description": "<p>How do you get on the road to being happier? Start by setting your alarm for 30 minutes earlier than usual and not hitting the snooze button. The effort required to leave that warm bed and enter the world is the same amount of effort needed to shake up your life and make that elusive change. In this humorous and provocative talk, Mel Robbins explains how turning off our brain's autopilot and demolishing our comfort zones is key to a rewarding life.</p><p><img src=\"/uploads/photo_1483985988355_763728e1935b_ixid_Mnwx_Mj_A3f_DB_8_M_Hxz_ZW_Fy_Y2h8_M_Xx8_Zm_Fza_Glvbnxlbnwwf_Hwwf_Hw_3_D_and_ixlib_rb_1_2_5186b4137a.1&amp;w=1000&amp;q=80\" alt=\"\"></p><p>Yet another image for fun <img src=\"/uploads/photo_1483985988355_763728e1935b_ixid_Mnwx_Mj_A3f_DB_8_M_Hxz_ZW_Fy_Y2h8_M_Xx8_Zm_Fza_Glvbnxlbnwwf_Hwwf_Hw_3_D_and_ixlib_rb_1_2_5186b4137a.1&amp;w=1000&amp;q=80\" alt=\"\"></p>", "published_at": "2021-08-05T13:06:47.325Z" } function addHost(str, host) { return str.split('src=\"/uploads').join(`src=\"${host}/uploads`) } console.log(addHost(data.Description, 'https://images.example.com'))

I would probably add the host to the Description property in the useEffect hook (although I'm not sure how your callApi() works).

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